Skip to content

Commit 8235072

Browse files
committed
fix(compiler-sfc): raise specific warning for failed extends and allow ignoring extends
ref #8286
1 parent f25bd37 commit 8235072

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts

+29
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,35 @@ describe('resolveType', () => {
755755
`)
756756
).not.toThrow()
757757
})
758+
759+
test('error against failed extends', () => {
760+
expect(() =>
761+
resolve(`
762+
import type Base from 'unknown'
763+
interface Props extends Base {}
764+
defineProps<Props>()
765+
`)
766+
).toThrow(`@vue-ignore`)
767+
})
768+
769+
test('allow ignoring failed extends', () => {
770+
let res: any
771+
772+
expect(
773+
() =>
774+
(res = resolve(`
775+
import type Base from 'unknown'
776+
interface Props extends /*@vue-ignore*/ Base {
777+
foo: string
778+
}
779+
defineProps<Props>()
780+
`))
781+
).not.toThrow(`@vue-ignore`)
782+
783+
expect(res.props).toStrictEqual({
784+
foo: ['String']
785+
})
786+
})
758787
})
759788
})
760789

packages/compiler-sfc/src/script/resolveType.ts

+22-4
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,29 @@ function resolveInterfaceMembers(
322322
const base = typeElementsToMap(ctx, node.body.body, node._ownerScope)
323323
if (node.extends) {
324324
for (const ext of node.extends) {
325-
const { props } = resolveTypeElements(ctx, ext, scope)
326-
for (const key in props) {
327-
if (!hasOwn(base.props, key)) {
328-
base.props[key] = props[key]
325+
if (
326+
ext.leadingComments &&
327+
ext.leadingComments.some(c => c.value.includes('@vue-ignore'))
328+
) {
329+
continue
330+
}
331+
try {
332+
const { props } = resolveTypeElements(ctx, ext, scope)
333+
for (const key in props) {
334+
if (!hasOwn(base.props, key)) {
335+
base.props[key] = props[key]
336+
}
329337
}
338+
} catch (e) {
339+
ctx.error(
340+
`Failed to resolve extends base type.\nIf this previously worked in 3.2, ` +
341+
`you can instruct the compiler to ignore this extend by adding ` +
342+
`/* @vue-ignore */ before it, for example:\n\n` +
343+
`interface Props extends /* @vue-ignore */ Base {}\n\n` +
344+
`Note: both in 3.2 or with the ignore, the properties in the base ` +
345+
`type are treated as fallthrough attrs at runtime.`,
346+
ext
347+
)
330348
}
331349
}
332350
}

0 commit comments

Comments
 (0)