test: more strict linking in dts tests

This commit is contained in:
Evan You 2023-02-03 21:41:33 +08:00
parent b49b9eff20
commit 1e0251a377
18 changed files with 157 additions and 212 deletions

View File

@ -1,4 +1,4 @@
import { createApp, App, Plugin } from './index' import { createApp, App, Plugin } from 'vue'
const app = createApp({}) const app = createApp({})

View File

@ -1,5 +1,4 @@
import { import {
expectType,
createBlock, createBlock,
VNode, VNode,
Teleport, Teleport,
@ -9,7 +8,8 @@ import {
Fragment, Fragment,
Suspense, Suspense,
defineComponent defineComponent
} from './index' } from 'vue'
import { expectType } from './utils'
expectType<VNode>(createBlock(Teleport)) expectType<VNode>(createBlock(Teleport))
expectType<VNode>(createBlock(Text)) expectType<VNode>(createBlock(Text))

View File

@ -1,20 +1,16 @@
import { import {
describe,
Component, Component,
defineComponent, defineComponent,
PropType, PropType,
ref, ref,
Ref, Ref,
expectError,
expectType,
ShallowUnwrapRef, ShallowUnwrapRef,
FunctionalComponent, FunctionalComponent,
ComponentPublicInstance, ComponentPublicInstance,
toRefs, toRefs,
IsAny, SetupContext
SetupContext, } from 'vue'
expectAssignable import { describe, expectAssignable, expectType, IsAny } from './utils'
} from './index'
declare function extractComponentOptions<Props, RawBindings>( declare function extractComponentOptions<Props, RawBindings>(
obj: Component<Props, RawBindings> obj: Component<Props, RawBindings>
@ -371,7 +367,7 @@ describe('array props', () => {
const { props, rawBindings, setup } = extractComponentOptions(MyComponent) const { props, rawBindings, setup } = extractComponentOptions(MyComponent)
// @ts-expect-error props should be readonly // @ts-expect-error props should be readonly
expectError((props.a = 1)) props.a = 1
expectType<any>(props.a) expectType<any>(props.a)
expectType<any>(props.b) expectType<any>(props.b)
@ -392,7 +388,7 @@ describe('array props', () => {
const { props, rawBindings, setup } = extractComponentOptions(MyComponent) const { props, rawBindings, setup } = extractComponentOptions(MyComponent)
// @ts-expect-error props should be readonly // @ts-expect-error props should be readonly
expectError((props.a = 1)) props.a = 1
// TODO infer the correct keys // TODO infer the correct keys
// expectType<any>(props.a) // expectType<any>(props.a)

View File

@ -1,6 +1,7 @@
import { defineComponent, expectError, expectType } from './index' import { defineComponent } from 'vue'
import { expectType } from './utils'
declare module '@vue/runtime-core' { declare module 'vue' {
interface ComponentCustomOptions { interface ComponentCustomOptions {
test?(n: number): void test?(n: number): void
} }
@ -31,20 +32,16 @@ export const Custom = defineComponent({
methods: { methods: {
aMethod() { aMethod() {
// @ts-expect-error
expectError(this.notExisting)
this.counter++ this.counter++
this.state = 'running' this.state = 'running'
this.$.appContext.config.globalProperties.state = 'running' this.$.appContext.config.globalProperties.state = 'running'
expectError(
// @ts-expect-error
(this.$.appContext.config.globalProperties.state = 'not valid')
)
// @ts-expect-error // @ts-expect-error
expectError((this.state = 'not valid')) this.notExisting
// @ts-expect-error
this.state = 'not valid'
// @ts-expect-error
this.$.appContext.config.globalProperties.state = 'not valid'
} }
} }
}) })
@ -57,10 +54,10 @@ expectType<JSX.Element>(<Custom ref={''} bar="bar" baz={1} />)
// @ts-expect-error // @ts-expect-error
expectType<JSX.Element>(<Custom />) expectType<JSX.Element>(<Custom />)
// @ts-expect-error // @ts-expect-error
expectError(<Custom bar="bar" />) ;<Custom bar="bar" />
// @ts-expect-error // @ts-expect-error
expectError(<Custom baz="baz" />) ;<Custom baz="baz" />
// @ts-expect-error // @ts-expect-error
expectError(<Custom baz={1} notExist={1} />) ;<Custom baz={1} notExist={1} />
// @ts-expect-error // @ts-expect-error
expectError(<Custom baz={1} custom="custom" />) ;<Custom baz={1} custom="custom" />

View File

@ -1,20 +1,16 @@
import { import {
describe,
test,
Component, Component,
defineComponent, defineComponent,
PropType, PropType,
ref, ref,
reactive, reactive,
createApp, createApp,
expectError,
expectType,
ComponentPublicInstance, ComponentPublicInstance,
ComponentOptions, ComponentOptions,
SetupContext, SetupContext,
IsUnion,
h h
} from './index' } from 'vue'
import { describe, expectType, IsUnion } from './utils'
describe('with object props', () => { describe('with object props', () => {
interface ExpectedProps { interface ExpectedProps {
@ -178,7 +174,7 @@ describe('with object props', () => {
expectType<ExpectedProps['lll']>(props.lll) expectType<ExpectedProps['lll']>(props.lll)
// @ts-expect-error props should be readonly // @ts-expect-error props should be readonly
expectError((props.a = 1)) props.a = 1
// setup context // setup context
return { return {
@ -220,7 +216,7 @@ describe('with object props', () => {
expectType<ExpectedProps['kkk']>(props.kkk) expectType<ExpectedProps['kkk']>(props.kkk)
// @ts-expect-error props should be readonly // @ts-expect-error props should be readonly
expectError((props.a = 1)) props.a = 1
// should also expose declared props on `this` // should also expose declared props on `this`
expectType<ExpectedProps['a']>(this.a) expectType<ExpectedProps['a']>(this.a)
@ -248,7 +244,7 @@ describe('with object props', () => {
expectType<ExpectedProps['kkk']>(this.kkk) expectType<ExpectedProps['kkk']>(this.kkk)
// @ts-expect-error props on `this` should be readonly // @ts-expect-error props on `this` should be readonly
expectError((this.a = 1)) this.a = 1
// assert setup context unwrapping // assert setup context unwrapping
expectType<number>(this.c) expectType<number>(this.c)
@ -305,18 +301,14 @@ describe('with object props', () => {
) )
// @ts-expect-error missing required props // @ts-expect-error missing required props
expectError(<MyComponent />) let c = <MyComponent />
// @ts-expect-error wrong prop types
c = <MyComponent a={'wrong type'} b="foo" dd={{ n: 1 }} ddd={['foo']} />
// @ts-expect-error wrong prop types
c = <MyComponent ggg="baz" />
expectError(
// @ts-expect-error wrong prop types
<MyComponent a={'wrong type'} b="foo" dd={{ n: 1 }} ddd={['foo']} />
)
expectError(
// @ts-expect-error wrong prop types
<MyComponent ggg="baz" />
)
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent b="foo" dd={{ n: 'string' }} ddd={['foo']} />) ;<MyComponent b="foo" dd={{ n: 'string' }} ddd={['foo']} />
// `this` should be void inside of prop validators and prop default factories // `this` should be void inside of prop validators and prop default factories
defineComponent({ defineComponent({
@ -353,17 +345,18 @@ describe('type inference w/ optional props declaration', () => {
expectType<JSX.Element>(<MyComponent msg="1" a={['1']} />) expectType<JSX.Element>(<MyComponent msg="1" a={['1']} />)
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent />) ;<MyComponent />
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent msg="1" />) ;<MyComponent msg="1" />
}) })
describe('type inference w/ direct setup function', () => { describe('type inference w/ direct setup function', () => {
const MyComponent = defineComponent((_props: { msg: string }) => {}) const MyComponent = defineComponent((_props: { msg: string }) => {})
expectType<JSX.Element>(<MyComponent msg="foo" />) expectType<JSX.Element>(<MyComponent msg="foo" />)
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent />) ;<MyComponent />
expectError(<MyComponent msg="1" />) // @ts-expect-error
;<MyComponent msg={1} />
}) })
describe('type inference w/ array props declaration', () => { describe('type inference w/ array props declaration', () => {
@ -371,7 +364,7 @@ describe('type inference w/ array props declaration', () => {
props: ['a', 'b'], props: ['a', 'b'],
setup(props) { setup(props) {
// @ts-expect-error props should be readonly // @ts-expect-error props should be readonly
expectError((props.a = 1)) props.a = 1
expectType<any>(props.a) expectType<any>(props.a)
expectType<any>(props.b) expectType<any>(props.b)
return { return {
@ -382,7 +375,7 @@ describe('type inference w/ array props declaration', () => {
expectType<any>(this.$props.a) expectType<any>(this.$props.a)
expectType<any>(this.$props.b) expectType<any>(this.$props.b)
// @ts-expect-error // @ts-expect-error
expectError((this.$props.a = 1)) this.$props.a = 1
expectType<any>(this.a) expectType<any>(this.a)
expectType<any>(this.b) expectType<any>(this.b)
expectType<number>(this.c) expectType<number>(this.c)
@ -390,7 +383,7 @@ describe('type inference w/ array props declaration', () => {
}) })
expectType<JSX.Element>(<MyComponent a={[1, 2]} b="b" />) expectType<JSX.Element>(<MyComponent a={[1, 2]} b="b" />)
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent other="other" />) ;<MyComponent other="other" />
}) })
describe('type inference w/ options API', () => { describe('type inference w/ options API', () => {
@ -609,17 +602,17 @@ describe('with mixins', () => {
// props should be readonly // props should be readonly
// @ts-expect-error // @ts-expect-error
expectError((this.aP1 = 'new')) this.aP1 = 'new'
// @ts-expect-error // @ts-expect-error
expectError((this.z = 1)) this.z = 1
// props on `this` should be readonly // props on `this` should be readonly
// @ts-expect-error // @ts-expect-error
expectError((this.bP1 = 1)) this.bP1 = 1
// string value can not assigned to number type value // string value can not assigned to number type value
// @ts-expect-error // @ts-expect-error
expectError((this.c = '1')) this.c = '1'
// setup context properties should be mutable // setup context properties should be mutable
this.d = 5 this.d = 5
@ -635,13 +628,13 @@ describe('with mixins', () => {
// missing required props // missing required props
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent />) ;<MyComponent />
// wrong prop types // wrong prop types
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent aP1="ap" aP2={'wrong type'} bP1="b" z={'z'} />) ;<MyComponent aP1="ap" aP2={'wrong type'} bP1="b" z={'z'} />
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent aP1={1} bP2={[1]} />) ;<MyComponent aP1={1} bP2={[1]} />
}) })
describe('with extends', () => { describe('with extends', () => {
@ -700,13 +693,13 @@ describe('with extends', () => {
// missing required props // missing required props
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent />) ;<MyComponent />
// wrong prop types // wrong prop types
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent aP2={'wrong type'} z={'z'} />) ;<MyComponent aP2={'wrong type'} z={'z'} />
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent aP1={3} />) ;<MyComponent aP1={3} />
}) })
describe('extends with mixins', () => { describe('extends with mixins', () => {
@ -805,19 +798,19 @@ describe('extends with mixins', () => {
// missing required props // missing required props
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent mP3 p3 /* z='z' */ />) ;<MyComponent mP3 p3 /* z='z' */ />
// missing required props from mixin // missing required props from mixin
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent /* mP3 */ p3 z="z" />) ;<MyComponent /* mP3 */ p3 z="z" />
// missing required props from extends // missing required props from extends
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent mP3 /* p3 */ z="z" />) ;<MyComponent mP3 /* p3 */ z="z" />
// wrong prop types // wrong prop types
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent p2={'wrong type'} z={'z'} />) ;<MyComponent p2={'wrong type'} z={'z'} />
// @ts-expect-error // @ts-expect-error
expectError(<MyComponent mP1={3} />) ;<MyComponent mP1={3} />
// #3468 // #3468
const CompWithD = defineComponent({ const CompWithD = defineComponent({
@ -875,14 +868,14 @@ describe('compatibility w/ createApp', () => {
}) })
describe('defineComponent', () => { describe('defineComponent', () => {
test('should accept components defined with defineComponent', () => { describe('should accept components defined with defineComponent', () => {
const comp = defineComponent({}) const comp = defineComponent({})
defineComponent({ defineComponent({
components: { comp } components: { comp }
}) })
}) })
test('should accept class components with receiving constructor arguments', () => { describe('should accept class components with receiving constructor arguments', () => {
class Comp { class Comp {
static __vccOpts = {} static __vccOpts = {}
constructor(_props: { foo: string }) {} constructor(_props: { foo: string }) {}
@ -915,29 +908,29 @@ describe('emits', () => {
emit('click', 1) emit('click', 1)
emit('input', 'foo') emit('input', 'foo')
// @ts-expect-error // @ts-expect-error
expectError(emit('nope')) emit('nope')
// @ts-expect-error // @ts-expect-error
expectError(emit('click')) emit('click')
// @ts-expect-error // @ts-expect-error
expectError(emit('click', 'foo')) emit('click', 'foo')
// @ts-expect-error // @ts-expect-error
expectError(emit('input')) emit('input')
// @ts-expect-error // @ts-expect-error
expectError(emit('input', 1)) emit('input', 1)
}, },
created() { created() {
this.$emit('click', 1) this.$emit('click', 1)
this.$emit('input', 'foo') this.$emit('input', 'foo')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('nope')) this.$emit('nope')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('click')) this.$emit('click')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('click', 'foo')) this.$emit('click', 'foo')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('input')) this.$emit('input')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('input', 1)) this.$emit('input', 1)
}, },
mounted() { mounted() {
// #3599 // #3599
@ -947,15 +940,15 @@ describe('emits', () => {
this.$emit('click', 1) this.$emit('click', 1)
this.$emit('input', 'foo') this.$emit('input', 'foo')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('nope')) this.$emit('nope')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('click')) this.$emit('click')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('click', 'foo')) this.$emit('click', 'foo')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('input')) this.$emit('input')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('input', 1)) this.$emit('input', 1)
}) })
} }
}) })
@ -970,14 +963,14 @@ describe('emits', () => {
emit('foo', 123) emit('foo', 123)
emit('bar') emit('bar')
// @ts-expect-error // @ts-expect-error
expectError(emit('nope')) emit('nope')
}, },
created() { created() {
this.$emit('foo') this.$emit('foo')
this.$emit('foo', 123) this.$emit('foo', 123)
this.$emit('bar') this.$emit('bar')
// @ts-expect-error // @ts-expect-error
expectError(this.$emit('nope')) this.$emit('nope')
} }
}) })
@ -990,9 +983,9 @@ describe('emits', () => {
expectType<((n: number) => any) | undefined>(props.onClick) expectType<((n: number) => any) | undefined>(props.onClick)
emit('click', 1) emit('click', 1)
// @ts-expect-error // @ts-expect-error
expectError(emit('click')) emit('click')
// @ts-expect-error // @ts-expect-error
expectError(emit('click', 'foo')) emit('click', 'foo')
} }
}) })
@ -1047,7 +1040,7 @@ describe('inject', () => {
expectType<unknown>(this.foo) expectType<unknown>(this.foo)
expectType<unknown>(this.bar) expectType<unknown>(this.bar)
// @ts-expect-error // @ts-expect-error
expectError((this.foobar = 1)) this.foobar = 1
} }
}) })
@ -1059,7 +1052,7 @@ describe('inject', () => {
expectType<unknown>(this.foo) expectType<unknown>(this.foo)
expectType<unknown>(this.bar) expectType<unknown>(this.bar)
// @ts-expect-error // @ts-expect-error
expectError((this.foobar = 1)) this.foobar = 1
} }
}) })
@ -1079,7 +1072,7 @@ describe('inject', () => {
expectType<unknown>(this.foo) expectType<unknown>(this.foo)
expectType<unknown>(this.bar) expectType<unknown>(this.bar)
// @ts-expect-error // @ts-expect-error
expectError((this.foobar = 1)) this.foobar = 1
} }
}) })
@ -1088,9 +1081,9 @@ describe('inject', () => {
props: ['a', 'b'], props: ['a', 'b'],
created() { created() {
// @ts-expect-error // @ts-expect-error
expectError((this.foo = 1)) this.foo = 1
// @ts-expect-error // @ts-expect-error
expectError((this.bar = 1)) this.bar = 1
} }
}) })
}) })
@ -1145,15 +1138,15 @@ describe('extract instance type', () => {
expectType<number>(compA.baseA) expectType<number>(compA.baseA)
// @ts-expect-error // @ts-expect-error
expectError((compA.a = true)) compA.a = true
// @ts-expect-error // @ts-expect-error
expectError((compA.b = 'foo')) compA.b = 'foo'
// @ts-expect-error // @ts-expect-error
expectError((compA.c = 1)) compA.c = 1
// @ts-expect-error // @ts-expect-error
expectError((compA.mA = 'foo')) compA.mA = 'foo'
// @ts-expect-error // @ts-expect-error
expectError((compA.baseA = 1)) compA.baseA = 1
}) })
describe('async setup', () => { describe('async setup', () => {
@ -1285,7 +1278,7 @@ import {
AllowedComponentProps, AllowedComponentProps,
ComponentCustomProps, ComponentCustomProps,
ExtractPropTypes ExtractPropTypes
} from './index' } from 'vue'
// code generated by tsc / vue-tsc, make sure this continues to work // code generated by tsc / vue-tsc, make sure this continues to work
// so we don't accidentally change the args order of DefineComponent // so we don't accidentally change the args order of DefineComponent

View File

@ -1,4 +1,5 @@
import { defineCustomElement, expectType, expectError, describe } from './index' import { defineCustomElement } from 'vue'
import { expectType, describe } from './utils'
describe('inject', () => { describe('inject', () => {
// with object inject // with object inject
@ -14,7 +15,7 @@ describe('inject', () => {
expectType<unknown>(this.foo) expectType<unknown>(this.foo)
expectType<unknown>(this.bar) expectType<unknown>(this.bar)
// @ts-expect-error // @ts-expect-error
expectError((this.foobar = 1)) this.foobar = 1
} }
}) })
@ -26,7 +27,7 @@ describe('inject', () => {
expectType<unknown>(this.foo) expectType<unknown>(this.foo)
expectType<unknown>(this.bar) expectType<unknown>(this.bar)
// @ts-expect-error // @ts-expect-error
expectError((this.foobar = 1)) this.foobar = 1
} }
}) })
@ -46,7 +47,7 @@ describe('inject', () => {
expectType<unknown>(this.foo) expectType<unknown>(this.foo)
expectType<unknown>(this.bar) expectType<unknown>(this.bar)
// @ts-expect-error // @ts-expect-error
expectError((this.foobar = 1)) this.foobar = 1
} }
}) })
@ -55,9 +56,9 @@ describe('inject', () => {
props: ['a', 'b'], props: ['a', 'b'],
created() { created() {
// @ts-expect-error // @ts-expect-error
expectError((this.foo = 1)) this.foo = 1
// @ts-expect-error // @ts-expect-error
expectError((this.bar = 1)) this.bar = 1
} }
}) })
}) })

View File

@ -1,11 +1,5 @@
import { import { h, Text, FunctionalComponent, Component } from 'vue'
h, import { expectType } from './utils'
Text,
FunctionalComponent,
expectError,
expectType,
Component
} from './index'
// simple function signature // simple function signature
const Foo = (props: { foo: number }) => h(Text, null, props.foo) const Foo = (props: { foo: number }) => h(Text, null, props.foo)
@ -15,11 +9,11 @@ expectType<JSX.Element>(<Foo foo={1} />)
expectType<JSX.Element>(<Foo foo={1} key="1" />) expectType<JSX.Element>(<Foo foo={1} key="1" />)
expectType<JSX.Element>(<Foo foo={1} ref="ref" />) expectType<JSX.Element>(<Foo foo={1} ref="ref" />)
// @ts-expect-error // @ts-expect-error
expectError(<Foo />) ;<Foo />
// @ts-expect-error // @ts-expect-error
expectError(<Foo foo="bar" />) ;<Foo foo="bar" />
// @ts-expect-error // @ts-expect-error
expectError(<Foo baz="bar" />) ;<Foo baz="bar" />
// Explicit signature with props + emits // Explicit signature with props + emits
const Bar: FunctionalComponent< const Bar: FunctionalComponent<
@ -30,11 +24,11 @@ const Bar: FunctionalComponent<
emit('update', 123) emit('update', 123)
// @ts-expect-error // @ts-expect-error
expectError(emit('nope')) emit('nope')
// @ts-expect-error // @ts-expect-error
expectError(emit('update')) emit('update')
// @ts-expect-error // @ts-expect-error
expectError(emit('update', 'nope')) emit('update', 'nope')
} }
// assigning runtime options // assigning runtime options
@ -42,22 +36,22 @@ Bar.props = {
foo: Number foo: Number
} }
// @ts-expect-error // @ts-expect-error
expectError((Bar.props = { foo: String })) Bar.props = { foo: String }
Bar.emits = { Bar.emits = {
update: value => value > 1 update: value => value > 1
} }
// @ts-expect-error // @ts-expect-error
expectError((Bar.emits = { baz: () => void 0 })) Bar.emits = { baz: () => void 0 }
// TSX // TSX
expectType<JSX.Element>(<Bar foo={1} />) expectType<JSX.Element>(<Bar foo={1} />)
// @ts-expect-error // @ts-expect-error
expectError(<Foo />) ;<Foo />
// @ts-expect-error // @ts-expect-error
expectError(<Bar foo="bar" />) ;<Bar foo="bar" />
// @ts-expect-error // @ts-expect-error
expectError(<Foo baz="bar" />) ;<Foo baz="bar" />
const Baz: FunctionalComponent<{}, string[]> = (props, { emit }) => { const Baz: FunctionalComponent<{}, string[]> = (props, { emit }) => {
expectType<{}>(props) expectType<{}>(props)

View File

@ -1,5 +1,4 @@
import { import {
describe,
h, h,
defineComponent, defineComponent,
ref, ref,
@ -7,29 +6,28 @@ import {
Teleport, Teleport,
Suspense, Suspense,
Component, Component,
expectError,
expectAssignable,
resolveComponent resolveComponent
} from './index' } from 'vue'
import { describe, expectAssignable } from './utils'
describe('h inference w/ element', () => { describe('h inference w/ element', () => {
// key // key
h('div', { key: 1 }) h('div', { key: 1 })
h('div', { key: 'foo' }) h('div', { key: 'foo' })
// @ts-expect-error // @ts-expect-error
expectError(h('div', { key: [] })) h('div', { key: [] })
// @ts-expect-error // @ts-expect-error
expectError(h('div', { key: {} })) h('div', { key: {} })
// ref // ref
h('div', { ref: 'foo' }) h('div', { ref: 'foo' })
h('div', { ref: ref(null) }) h('div', { ref: ref(null) })
h('div', { ref: _el => {} }) h('div', { ref: _el => {} })
// @ts-expect-error // @ts-expect-error
expectError(h('div', { ref: [] })) h('div', { ref: [] })
// @ts-expect-error // @ts-expect-error
expectError(h('div', { ref: {} })) h('div', { ref: {} })
// @ts-expect-error // @ts-expect-error
expectError(h('div', { ref: 123 })) h('div', { ref: 123 })
// slots // slots
const slots = { default: () => {} } // RawSlots const slots = { default: () => {} } // RawSlots
h('div', {}, slots) h('div', {}, slots)
@ -40,20 +38,20 @@ describe('h inference w/ Fragment', () => {
h(Fragment, ['hello']) h(Fragment, ['hello'])
h(Fragment, { key: 123 }, ['hello']) h(Fragment, { key: 123 }, ['hello'])
// @ts-expect-error // @ts-expect-error
expectError(h(Fragment, 'foo')) h(Fragment, 'foo')
// @ts-expect-error // @ts-expect-error
expectError(h(Fragment, { key: 123 }, 'bar')) h(Fragment, { key: 123 }, 'bar')
}) })
describe('h inference w/ Teleport', () => { describe('h inference w/ Teleport', () => {
h(Teleport, { to: '#foo' }, 'hello') h(Teleport, { to: '#foo' }, 'hello')
h(Teleport, { to: '#foo' }, { default() {} }) h(Teleport, { to: '#foo' }, { default() {} })
// @ts-expect-error // @ts-expect-error
expectError(h(Teleport)) h(Teleport)
// @ts-expect-error // @ts-expect-error
expectError(h(Teleport, {})) h(Teleport, {})
// @ts-expect-error // @ts-expect-error
expectError(h(Teleport, { to: '#foo' })) h(Teleport, { to: '#foo' })
}) })
describe('h inference w/ Suspense', () => { describe('h inference w/ Suspense', () => {
@ -64,7 +62,7 @@ describe('h inference w/ Suspense', () => {
default: () => 'foo' default: () => 'foo'
}) })
// @ts-expect-error // @ts-expect-error
expectError(h(Suspense, { onResolve: 1 })) h(Suspense, { onResolve: 1 })
}) })
describe('h inference w/ functional component', () => { describe('h inference w/ functional component', () => {
@ -72,11 +70,11 @@ describe('h inference w/ functional component', () => {
h(Func, { foo: 'hello' }) h(Func, { foo: 'hello' })
h(Func, { foo: 'hello', bar: 123 }) h(Func, { foo: 'hello', bar: 123 })
// @ts-expect-error // @ts-expect-error
expectError(h(Func, { foo: 123 })) h(Func, { foo: 123 })
// @ts-expect-error // @ts-expect-error
expectError(h(Func, {})) h(Func, {})
// @ts-expect-error // @ts-expect-error
expectError(h(Func, { bar: 123 })) h(Func, { bar: 123 })
}) })
describe('h support w/ plain object component', () => { describe('h support w/ plain object component', () => {
@ -106,11 +104,11 @@ describe('h inference w/ defineComponent', () => {
// should allow extraneous props (attrs fallthrough) // should allow extraneous props (attrs fallthrough)
h(Foo, { bar: 1, foo: 'ok', class: 'extra' }) h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
// @ts-expect-error should fail on missing required prop // @ts-expect-error should fail on missing required prop
expectError(h(Foo, {})) h(Foo, {})
// @ts-expect-error // @ts-expect-error
expectError(h(Foo, { foo: 'ok' })) h(Foo, { foo: 'ok' })
// @ts-expect-error should fail on wrong type // @ts-expect-error should fail on wrong type
expectError(h(Foo, { bar: 1, foo: 1 })) h(Foo, { bar: 1, foo: 1 })
}) })
// describe('h inference w/ defineComponent + optional props', () => { // describe('h inference w/ defineComponent + optional props', () => {
@ -123,11 +121,11 @@ describe('h inference w/ defineComponent', () => {
// // should allow extraneous props (attrs fallthrough) // // should allow extraneous props (attrs fallthrough)
// h(Foo, { bar: 1, foo: 'ok', class: 'extra' }) // h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
// // @ts-expect-error should fail on missing required prop // // @ts-expect-error should fail on missing required prop
// expectError(h(Foo, {})) // h(Foo, {})
// // @ts-expect-error // // @ts-expect-error
// expectError(h(Foo, { foo: 'ok' })) // h(Foo, { foo: 'ok' })
// // @ts-expect-error should fail on wrong type // // @ts-expect-error should fail on wrong type
// expectError(h(Foo, { bar: 1, foo: 1 })) // h(Foo, { bar: 1, foo: 1 })
// }) // })
// describe('h inference w/ defineComponent + direct function', () => { // describe('h inference w/ defineComponent + direct function', () => {
@ -138,11 +136,11 @@ describe('h inference w/ defineComponent', () => {
// // should allow extraneous props (attrs fallthrough) // // should allow extraneous props (attrs fallthrough)
// h(Foo, { bar: 1, foo: 'ok', class: 'extra' }) // h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
// // @ts-expect-error should fail on missing required prop // // @ts-expect-error should fail on missing required prop
// expectError(h(Foo, {})) // h(Foo, {})
// // @ts-expect-error // // @ts-expect-error
// expectError(h(Foo, { foo: 'ok' })) // h(Foo, { foo: 'ok' })
// // @ts-expect-error should fail on wrong type // // @ts-expect-error should fail on wrong type
// expectError(h(Foo, { bar: 1, foo: 1 })) // h(Foo, { bar: 1, foo: 1 })
// }) // })
// #922 and #3218 // #922 and #3218
@ -223,7 +221,7 @@ describe('Boolean prop implicit false', () => {
visible: true visible: true
}) })
// @ts-expect-error // @ts-expect-error
expectError(h(RequiredComponent, {})) h(RequiredComponent, {})
}) })
// #2357 // #2357

View File

@ -1,4 +1,5 @@
import { provide, inject, InjectionKey, expectType } from './index' import { provide, inject, InjectionKey } from 'vue'
import { expectType } from './utils'
const key: InjectionKey<number> = Symbol() const key: InjectionKey<number> = Symbol()

View File

@ -2,9 +2,6 @@
"name": "dts-test", "name": "dts-test",
"private": true, "private": true,
"dependencies": { "dependencies": {
"vue": "workspace:*", "vue": "workspace:*"
"@vue/runtime-core": "workspace:*",
"@vue/runtime-dom": "workspace:*",
"@vue/reactivity": "workspace:*"
} }
} }

View File

@ -1,21 +1,12 @@
import { import { ref, readonly, shallowReadonly, Ref, reactive, markRaw } from 'vue'
ref, import { describe, expectType } from './utils'
readonly,
shallowReadonly,
describe,
expectError,
expectType,
Ref,
reactive,
markRaw
} from './index'
describe('should support DeepReadonly', () => { describe('should support DeepReadonly', () => {
const r = readonly({ obj: { k: 'v' } }) const r = readonly({ obj: { k: 'v' } })
// @ts-expect-error // @ts-expect-error
expectError((r.obj = {})) r.obj = {}
// @ts-expect-error // @ts-expect-error
expectError((r.obj.k = 'x')) r.obj.k = 'x'
}) })
// #4180 // #4180

View File

@ -1,13 +1,7 @@
import { import { ref, computed, Ref, ComputedRef, WritableComputedRef } from 'vue'
expectType,
ref,
computed,
Ref,
ComputedRef,
WritableComputedRef
} from './index'
import 'vue/macros-global' import 'vue/macros-global'
import { RefType, RefTypes } from 'vue/macros' import { RefType, RefTypes } from 'vue/macros'
import { expectType } from './utils'
// wrapping refs // wrapping refs

View File

@ -5,15 +5,14 @@ import {
isRef, isRef,
unref, unref,
reactive, reactive,
expectType,
proxyRefs, proxyRefs,
toRef, toRef,
toRefs, toRefs,
ToRefs, ToRefs,
shallowReactive, shallowReactive,
readonly, readonly
describe } from 'vue'
} from './index' import { expectType, describe } from './utils'
function plainType(arg: number | Ref<number>) { function plainType(arg: number | Ref<number>) {
// ref coercing // ref coercing

View File

@ -1,13 +1,12 @@
import { import {
expectType,
defineProps, defineProps,
defineEmits, defineEmits,
useAttrs, useAttrs,
useSlots, useSlots,
withDefaults, withDefaults,
Slots, Slots
describe } from 'vue'
} from './index' import { describe, expectType } from './utils'
describe('defineProps w/ type declaration', () => { describe('defineProps w/ type declaration', () => {
// type declaration // type declaration

View File

@ -1,13 +1,6 @@
// TSX w/ defineComponent is tested in defineComponent.test-d.tsx // TSX w/ defineComponent is tested in defineComponent.test-d.tsx
import { import { KeepAlive, Suspense, Fragment, Teleport, VNode } from 'vue'
KeepAlive, import { expectType } from './utils'
Suspense,
Fragment,
Teleport,
expectError,
expectType,
VNode
} from './index'
expectType<VNode>(<div />) expectType<VNode>(<div />)
expectType<JSX.Element>(<div />) expectType<JSX.Element>(<div />)
@ -15,7 +8,7 @@ expectType<JSX.Element>(<div id="foo" />)
expectType<JSX.Element>(<input value="foo" />) expectType<JSX.Element>(<input value="foo" />)
// @ts-expect-error style css property validation // @ts-expect-error style css property validation
expectError(<div style={{ unknown: 123 }} />) ;<div style={{ unknown: 123 }} />
// allow array styles and nested array styles // allow array styles and nested array styles
expectType<JSX.Element>(<div style={[{ color: 'red' }]} />) expectType<JSX.Element>(<div style={[{ color: 'red' }]} />)
@ -24,7 +17,7 @@ expectType<JSX.Element>(
) )
// @ts-expect-error unknown prop // @ts-expect-error unknown prop
expectError(<div foo="bar" />) ;<div foo="bar" />
// allow key/ref on arbitrary element // allow key/ref on arbitrary element
expectType<JSX.Element>(<div key="foo" />) expectType<JSX.Element>(<div key="foo" />)
@ -47,15 +40,15 @@ expectType<JSX.Element>(<Teleport to="#foo" />)
expectType<JSX.Element>(<Teleport to="#foo" key="1" />) expectType<JSX.Element>(<Teleport to="#foo" key="1" />)
// @ts-expect-error // @ts-expect-error
expectError(<Teleport />) ;<Teleport />
// @ts-expect-error // @ts-expect-error
expectError(<Teleport to={1} />) ;<Teleport to={1} />
// KeepAlive // KeepAlive
expectType<JSX.Element>(<KeepAlive include="foo" exclude={['a']} />) expectType<JSX.Element>(<KeepAlive include="foo" exclude={['a']} />)
expectType<JSX.Element>(<KeepAlive key="1" />) expectType<JSX.Element>(<KeepAlive key="1" />)
// @ts-expect-error // @ts-expect-error
expectError(<KeepAlive include={123} />) ;<KeepAlive include={123} />
// Suspense // Suspense
expectType<JSX.Element>(<Suspense />) expectType<JSX.Element>(<Suspense />)
@ -64,4 +57,4 @@ expectType<JSX.Element>(
<Suspense onResolve={() => {}} onFallback={() => {}} onPending={() => {}} /> <Suspense onResolve={() => {}} onFallback={() => {}} onPending={() => {}} />
) )
// @ts-expect-error // @ts-expect-error
expectError(<Suspense onResolve={123} />) ;<Suspense onResolve={123} />

View File

@ -1,13 +1,10 @@
// This directory contains a number of d.ts assertions // This directory contains a number of d.ts assertions
// use \@ts-expect-error where errors are expected. // use \@ts-expect-error where errors are expected.
export * from 'vue'
export function describe(_name: string, _fn: () => void): void export function describe(_name: string, _fn: () => void): void
export function test(_name: string, _fn: () => any): void export function test(_name: string, _fn: () => any): void
export function expectType<T>(value: T): void export function expectType<T>(value: T): void
export function expectError<T>(value: T): void
export function expectAssignable<T, T2 extends T = T>(value: T2): void export function expectAssignable<T, T2 extends T = T>(value: T2): void
export type IsUnion<T, U extends T = T> = ( export type IsUnion<T, U extends T = T> = (

View File

@ -1,4 +1,5 @@
import { ref, computed, watch, expectType, defineComponent } from './index' import { ref, computed, watch, defineComponent } from 'vue'
import { expectType } from './utils'
const source = ref('foo') const source = ref('foo')
const source2 = computed(() => source.value) const source2 = computed(() => source.value)

View File

@ -182,14 +182,8 @@ importers:
packages/dts-test: packages/dts-test:
specifiers: specifiers:
'@vue/reactivity': workspace:*
'@vue/runtime-core': workspace:*
'@vue/runtime-dom': workspace:*
vue: workspace:* vue: workspace:*
dependencies: dependencies:
'@vue/reactivity': link:../reactivity
'@vue/runtime-core': link:../runtime-core
'@vue/runtime-dom': link:../runtime-dom
vue: link:../vue vue: link:../vue
packages/reactivity: packages/reactivity: