diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cfad47b65336f..fd57b9b924354 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15587,11 +15587,14 @@ namespace ts { if (inferFromMatchingType(source, (target).types, isTypeCloselyMatchedBy)) return; } } - else if (target.flags & TypeFlags.Intersection && some((target).types, t => !!getInferenceInfoForType(t))) { + else if (target.flags & TypeFlags.Intersection && some((target).types, + t => !!getInferenceInfoForType(t) || (isGenericMappedType(t) && !!getInferenceInfoForType(getHomomorphicTypeVariable(t) || neverType)))) { // We reduce intersection types only when they contain naked type parameters. For example, when // inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and // infer { extra: any } for T. But when inferring to 'string[] & Iterable' we want to keep the // string[] on the source side and infer string for T. + // Likewise, we consider a homomorphic mapped type constrainted to the target type parameter as similar to a "naked type variable" + // in such scenarios. if (source.flags & TypeFlags.Intersection) { // Infer between identically matching source and target constituents and remove the matching types. const [sources, targets] = inferFromMatchingTypes((source).types, (target).types, isTypeIdenticalTo); diff --git a/tests/baselines/reference/vueLikeDataAndPropsInference.js b/tests/baselines/reference/vueLikeDataAndPropsInference.js new file mode 100644 index 0000000000000..805bda224e988 --- /dev/null +++ b/tests/baselines/reference/vueLikeDataAndPropsInference.js @@ -0,0 +1,63 @@ +//// [vueLikeDataAndPropsInference.ts] +interface Instance { + _instanceBrand: never +} + +type DataDef = (this: Readonly & Instance) => Data + +type PropsDefinition = { + [K in keyof T]: T[K] +} + +interface Options< + Data = ((this: Instance) => object), + PropsDef = {} + > { + data?: Data + props?: PropsDef + watch?: Record> +} + +type WatchHandler = (val: T, oldVal: T) => void; + +type ThisTypedOptions = + Options, PropsDefinition> & + ThisType & Instance> + +declare function test(fn: ThisTypedOptions): void; +declare function test(fn: Options): void; + +test({ + props: { + foo: '' + }, + + data(): { bar: boolean } { + return { + bar: true + } + }, + + watch: { + foo(newVal: string, oldVal: string): void { + this.bar = false + } + } +}) + +//// [vueLikeDataAndPropsInference.js] +test({ + props: { + foo: '' + }, + data: function () { + return { + bar: true + }; + }, + watch: { + foo: function (newVal, oldVal) { + this.bar = false; + } + } +}); diff --git a/tests/baselines/reference/vueLikeDataAndPropsInference.symbols b/tests/baselines/reference/vueLikeDataAndPropsInference.symbols new file mode 100644 index 0000000000000..73ca11cf79253 --- /dev/null +++ b/tests/baselines/reference/vueLikeDataAndPropsInference.symbols @@ -0,0 +1,130 @@ +=== tests/cases/compiler/vueLikeDataAndPropsInference.ts === +interface Instance { +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference.ts, 0, 0)) + + _instanceBrand: never +>_instanceBrand : Symbol(Instance._instanceBrand, Decl(vueLikeDataAndPropsInference.ts, 0, 20)) +} + +type DataDef = (this: Readonly & Instance) => Data +>DataDef : Symbol(DataDef, Decl(vueLikeDataAndPropsInference.ts, 2, 1)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 4, 13)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 4, 18)) +>this : Symbol(this, Decl(vueLikeDataAndPropsInference.ts, 4, 29)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 4, 18)) +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference.ts, 0, 0)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 4, 13)) + +type PropsDefinition = { +>PropsDefinition : Symbol(PropsDefinition, Decl(vueLikeDataAndPropsInference.ts, 4, 70)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference.ts, 6, 21)) + + [K in keyof T]: T[K] +>K : Symbol(K, Decl(vueLikeDataAndPropsInference.ts, 7, 5)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference.ts, 6, 21)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference.ts, 6, 21)) +>K : Symbol(K, Decl(vueLikeDataAndPropsInference.ts, 7, 5)) +} + +interface Options< +>Options : Symbol(Options, Decl(vueLikeDataAndPropsInference.ts, 8, 1)) + + Data = ((this: Instance) => object), +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 10, 18)) +>this : Symbol(this, Decl(vueLikeDataAndPropsInference.ts, 11, 13)) +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference.ts, 0, 0)) + + PropsDef = {} +>PropsDef : Symbol(PropsDef, Decl(vueLikeDataAndPropsInference.ts, 11, 40)) + + > { + data?: Data +>data : Symbol(Options.data, Decl(vueLikeDataAndPropsInference.ts, 13, 7)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 10, 18)) + + props?: PropsDef +>props : Symbol(Options.props, Decl(vueLikeDataAndPropsInference.ts, 14, 15)) +>PropsDef : Symbol(PropsDef, Decl(vueLikeDataAndPropsInference.ts, 11, 40)) + + watch?: Record> +>watch : Symbol(Options.watch, Decl(vueLikeDataAndPropsInference.ts, 15, 20)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>WatchHandler : Symbol(WatchHandler, Decl(vueLikeDataAndPropsInference.ts, 17, 1)) +} + +type WatchHandler = (val: T, oldVal: T) => void; +>WatchHandler : Symbol(WatchHandler, Decl(vueLikeDataAndPropsInference.ts, 17, 1)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference.ts, 19, 18)) +>val : Symbol(val, Decl(vueLikeDataAndPropsInference.ts, 19, 24)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference.ts, 19, 18)) +>oldVal : Symbol(oldVal, Decl(vueLikeDataAndPropsInference.ts, 19, 31)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference.ts, 19, 18)) + +type ThisTypedOptions = +>ThisTypedOptions : Symbol(ThisTypedOptions, Decl(vueLikeDataAndPropsInference.ts, 19, 51)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 21, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 21, 27)) + + Options, PropsDefinition> & +>Options : Symbol(Options, Decl(vueLikeDataAndPropsInference.ts, 8, 1)) +>DataDef : Symbol(DataDef, Decl(vueLikeDataAndPropsInference.ts, 2, 1)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 21, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 21, 27)) +>PropsDefinition : Symbol(PropsDefinition, Decl(vueLikeDataAndPropsInference.ts, 4, 70)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 21, 27)) + + ThisType & Instance> +>ThisType : Symbol(ThisType, Decl(lib.es5.d.ts, --, --)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 21, 22)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 21, 27)) +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference.ts, 0, 0)) + +declare function test(fn: ThisTypedOptions): void; +>test : Symbol(test, Decl(vueLikeDataAndPropsInference.ts, 23, 47), Decl(vueLikeDataAndPropsInference.ts, 25, 76)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 25, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 25, 27)) +>fn : Symbol(fn, Decl(vueLikeDataAndPropsInference.ts, 25, 35)) +>ThisTypedOptions : Symbol(ThisTypedOptions, Decl(vueLikeDataAndPropsInference.ts, 19, 51)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference.ts, 25, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference.ts, 25, 27)) + +declare function test(fn: Options): void; +>test : Symbol(test, Decl(vueLikeDataAndPropsInference.ts, 23, 47), Decl(vueLikeDataAndPropsInference.ts, 25, 76)) +>fn : Symbol(fn, Decl(vueLikeDataAndPropsInference.ts, 26, 22)) +>Options : Symbol(Options, Decl(vueLikeDataAndPropsInference.ts, 8, 1)) + +test({ +>test : Symbol(test, Decl(vueLikeDataAndPropsInference.ts, 23, 47), Decl(vueLikeDataAndPropsInference.ts, 25, 76)) + + props: { +>props : Symbol(props, Decl(vueLikeDataAndPropsInference.ts, 28, 6)) + + foo: '' +>foo : Symbol(foo, Decl(vueLikeDataAndPropsInference.ts, 29, 12)) + + }, + + data(): { bar: boolean } { +>data : Symbol(data, Decl(vueLikeDataAndPropsInference.ts, 31, 6)) +>bar : Symbol(bar, Decl(vueLikeDataAndPropsInference.ts, 33, 13)) + + return { + bar: true +>bar : Symbol(bar, Decl(vueLikeDataAndPropsInference.ts, 34, 16)) + } + }, + + watch: { +>watch : Symbol(watch, Decl(vueLikeDataAndPropsInference.ts, 37, 6)) + + foo(newVal: string, oldVal: string): void { +>foo : Symbol(foo, Decl(vueLikeDataAndPropsInference.ts, 39, 12)) +>newVal : Symbol(newVal, Decl(vueLikeDataAndPropsInference.ts, 40, 12)) +>oldVal : Symbol(oldVal, Decl(vueLikeDataAndPropsInference.ts, 40, 27)) + + this.bar = false + } + } +}) diff --git a/tests/baselines/reference/vueLikeDataAndPropsInference.types b/tests/baselines/reference/vueLikeDataAndPropsInference.types new file mode 100644 index 0000000000000..13f40a37a7839 --- /dev/null +++ b/tests/baselines/reference/vueLikeDataAndPropsInference.types @@ -0,0 +1,97 @@ +=== tests/cases/compiler/vueLikeDataAndPropsInference.ts === +interface Instance { + _instanceBrand: never +>_instanceBrand : never +} + +type DataDef = (this: Readonly & Instance) => Data +>DataDef : DataDef +>this : Readonly & Instance + +type PropsDefinition = { +>PropsDefinition : PropsDefinition + + [K in keyof T]: T[K] +} + +interface Options< + Data = ((this: Instance) => object), +>this : Instance + + PropsDef = {} + > { + data?: Data +>data : Data + + props?: PropsDef +>props : PropsDef + + watch?: Record> +>watch : Record> +} + +type WatchHandler = (val: T, oldVal: T) => void; +>WatchHandler : WatchHandler +>val : T +>oldVal : T + +type ThisTypedOptions = +>ThisTypedOptions : ThisTypedOptions + + Options, PropsDefinition> & + ThisType & Instance> + +declare function test(fn: ThisTypedOptions): void; +>test : { (fn: ThisTypedOptions): void; (fn: Options<(this: Instance) => object, {}>): void; } +>fn : ThisTypedOptions + +declare function test(fn: Options): void; +>test : { (fn: ThisTypedOptions): void; (fn: Options<(this: Instance) => object, {}>): void; } +>fn : Options<(this: Instance) => object, {}> + +test({ +>test({ props: { foo: '' }, data(): { bar: boolean } { return { bar: true } }, watch: { foo(newVal: string, oldVal: string): void { this.bar = false } }}) : void +>test : { (fn: ThisTypedOptions): void; (fn: Options<(this: Instance) => object, {}>): void; } +>{ props: { foo: '' }, data(): { bar: boolean } { return { bar: true } }, watch: { foo(newVal: string, oldVal: string): void { this.bar = false } }} : { props: { foo: string; }; data(this: Readonly<{ foo: string; }> & Instance): { bar: boolean; }; watch: { foo(newVal: string, oldVal: string): void; }; } + + props: { +>props : { foo: string; } +>{ foo: '' } : { foo: string; } + + foo: '' +>foo : string +>'' : "" + + }, + + data(): { bar: boolean } { +>data : (this: Readonly<{ foo: string; }> & Instance) => { bar: boolean; } +>bar : boolean + + return { +>{ bar: true } : { bar: true; } + + bar: true +>bar : true +>true : true + } + }, + + watch: { +>watch : { foo(newVal: string, oldVal: string): void; } +>{ foo(newVal: string, oldVal: string): void { this.bar = false } } : { foo(newVal: string, oldVal: string): void; } + + foo(newVal: string, oldVal: string): void { +>foo : (newVal: string, oldVal: string) => void +>newVal : string +>oldVal : string + + this.bar = false +>this.bar = false : false +>this.bar : any +>this : any +>bar : any +>false : false + } + } +}) diff --git a/tests/baselines/reference/vueLikeDataAndPropsInference2.js b/tests/baselines/reference/vueLikeDataAndPropsInference2.js new file mode 100644 index 0000000000000..2a203cb437cbb --- /dev/null +++ b/tests/baselines/reference/vueLikeDataAndPropsInference2.js @@ -0,0 +1,64 @@ +//// [vueLikeDataAndPropsInference2.ts] +interface Instance { + _instanceBrand: never +} + +type DataDef = (this: Readonly & Instance) => Data + +type PropsDefinition = { + [K in keyof T]: T[K] +} + +interface Options< + Data = object | ((this: Instance) => object), + PropsDef = PropsDefinition> + > { + data?: Data + props?: PropsDef + watch?: Record> +} + +type WatchHandler = (val: T, oldVal: T) => void; + +type ThisTypedOptions = + object & + Options, PropsDefinition> & + ThisType & Instance> + +declare function test(fn: ThisTypedOptions): void; +declare function test(fn: Options): void; + +test({ + props: { + foo: '' + }, + + data(): { bar: boolean } { + return { + bar: true + } + }, + + watch: { + foo(newVal: string, oldVal: string): void { + this.bar = false + } + } +}) + +//// [vueLikeDataAndPropsInference2.js] +test({ + props: { + foo: '' + }, + data: function () { + return { + bar: true + }; + }, + watch: { + foo: function (newVal, oldVal) { + this.bar = false; + } + } +}); diff --git a/tests/baselines/reference/vueLikeDataAndPropsInference2.symbols b/tests/baselines/reference/vueLikeDataAndPropsInference2.symbols new file mode 100644 index 0000000000000..c7d102bbcb9db --- /dev/null +++ b/tests/baselines/reference/vueLikeDataAndPropsInference2.symbols @@ -0,0 +1,133 @@ +=== tests/cases/compiler/vueLikeDataAndPropsInference2.ts === +interface Instance { +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference2.ts, 0, 0)) + + _instanceBrand: never +>_instanceBrand : Symbol(Instance._instanceBrand, Decl(vueLikeDataAndPropsInference2.ts, 0, 20)) +} + +type DataDef = (this: Readonly & Instance) => Data +>DataDef : Symbol(DataDef, Decl(vueLikeDataAndPropsInference2.ts, 2, 1)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 4, 13)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 4, 18)) +>this : Symbol(this, Decl(vueLikeDataAndPropsInference2.ts, 4, 29)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 4, 18)) +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference2.ts, 0, 0)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 4, 13)) + +type PropsDefinition = { +>PropsDefinition : Symbol(PropsDefinition, Decl(vueLikeDataAndPropsInference2.ts, 4, 70)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference2.ts, 6, 21)) + + [K in keyof T]: T[K] +>K : Symbol(K, Decl(vueLikeDataAndPropsInference2.ts, 7, 5)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference2.ts, 6, 21)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference2.ts, 6, 21)) +>K : Symbol(K, Decl(vueLikeDataAndPropsInference2.ts, 7, 5)) +} + +interface Options< +>Options : Symbol(Options, Decl(vueLikeDataAndPropsInference2.ts, 8, 1)) + + Data = object | ((this: Instance) => object), +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 10, 18)) +>this : Symbol(this, Decl(vueLikeDataAndPropsInference2.ts, 11, 22)) +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference2.ts, 0, 0)) + + PropsDef = PropsDefinition> +>PropsDef : Symbol(PropsDef, Decl(vueLikeDataAndPropsInference2.ts, 11, 49)) +>PropsDefinition : Symbol(PropsDefinition, Decl(vueLikeDataAndPropsInference2.ts, 4, 70)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + > { + data?: Data +>data : Symbol(Options.data, Decl(vueLikeDataAndPropsInference2.ts, 13, 7)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 10, 18)) + + props?: PropsDef +>props : Symbol(Options.props, Decl(vueLikeDataAndPropsInference2.ts, 14, 15)) +>PropsDef : Symbol(PropsDef, Decl(vueLikeDataAndPropsInference2.ts, 11, 49)) + + watch?: Record> +>watch : Symbol(Options.watch, Decl(vueLikeDataAndPropsInference2.ts, 15, 20)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>WatchHandler : Symbol(WatchHandler, Decl(vueLikeDataAndPropsInference2.ts, 17, 1)) +} + +type WatchHandler = (val: T, oldVal: T) => void; +>WatchHandler : Symbol(WatchHandler, Decl(vueLikeDataAndPropsInference2.ts, 17, 1)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference2.ts, 19, 18)) +>val : Symbol(val, Decl(vueLikeDataAndPropsInference2.ts, 19, 24)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference2.ts, 19, 18)) +>oldVal : Symbol(oldVal, Decl(vueLikeDataAndPropsInference2.ts, 19, 31)) +>T : Symbol(T, Decl(vueLikeDataAndPropsInference2.ts, 19, 18)) + +type ThisTypedOptions = +>ThisTypedOptions : Symbol(ThisTypedOptions, Decl(vueLikeDataAndPropsInference2.ts, 19, 51)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 21, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 21, 27)) + + object & + Options, PropsDefinition> & +>Options : Symbol(Options, Decl(vueLikeDataAndPropsInference2.ts, 8, 1)) +>DataDef : Symbol(DataDef, Decl(vueLikeDataAndPropsInference2.ts, 2, 1)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 21, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 21, 27)) +>PropsDefinition : Symbol(PropsDefinition, Decl(vueLikeDataAndPropsInference2.ts, 4, 70)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 21, 27)) + + ThisType & Instance> +>ThisType : Symbol(ThisType, Decl(lib.es5.d.ts, --, --)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 21, 22)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 21, 27)) +>Instance : Symbol(Instance, Decl(vueLikeDataAndPropsInference2.ts, 0, 0)) + +declare function test(fn: ThisTypedOptions): void; +>test : Symbol(test, Decl(vueLikeDataAndPropsInference2.ts, 24, 47), Decl(vueLikeDataAndPropsInference2.ts, 26, 76)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 26, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 26, 27)) +>fn : Symbol(fn, Decl(vueLikeDataAndPropsInference2.ts, 26, 35)) +>ThisTypedOptions : Symbol(ThisTypedOptions, Decl(vueLikeDataAndPropsInference2.ts, 19, 51)) +>Data : Symbol(Data, Decl(vueLikeDataAndPropsInference2.ts, 26, 22)) +>Props : Symbol(Props, Decl(vueLikeDataAndPropsInference2.ts, 26, 27)) + +declare function test(fn: Options): void; +>test : Symbol(test, Decl(vueLikeDataAndPropsInference2.ts, 24, 47), Decl(vueLikeDataAndPropsInference2.ts, 26, 76)) +>fn : Symbol(fn, Decl(vueLikeDataAndPropsInference2.ts, 27, 22)) +>Options : Symbol(Options, Decl(vueLikeDataAndPropsInference2.ts, 8, 1)) + +test({ +>test : Symbol(test, Decl(vueLikeDataAndPropsInference2.ts, 24, 47), Decl(vueLikeDataAndPropsInference2.ts, 26, 76)) + + props: { +>props : Symbol(props, Decl(vueLikeDataAndPropsInference2.ts, 29, 6)) + + foo: '' +>foo : Symbol(foo, Decl(vueLikeDataAndPropsInference2.ts, 30, 12)) + + }, + + data(): { bar: boolean } { +>data : Symbol(data, Decl(vueLikeDataAndPropsInference2.ts, 32, 6)) +>bar : Symbol(bar, Decl(vueLikeDataAndPropsInference2.ts, 34, 13)) + + return { + bar: true +>bar : Symbol(bar, Decl(vueLikeDataAndPropsInference2.ts, 35, 16)) + } + }, + + watch: { +>watch : Symbol(watch, Decl(vueLikeDataAndPropsInference2.ts, 38, 6)) + + foo(newVal: string, oldVal: string): void { +>foo : Symbol(foo, Decl(vueLikeDataAndPropsInference2.ts, 40, 12)) +>newVal : Symbol(newVal, Decl(vueLikeDataAndPropsInference2.ts, 41, 12)) +>oldVal : Symbol(oldVal, Decl(vueLikeDataAndPropsInference2.ts, 41, 27)) + + this.bar = false + } + } +}) diff --git a/tests/baselines/reference/vueLikeDataAndPropsInference2.types b/tests/baselines/reference/vueLikeDataAndPropsInference2.types new file mode 100644 index 0000000000000..6900535285add --- /dev/null +++ b/tests/baselines/reference/vueLikeDataAndPropsInference2.types @@ -0,0 +1,98 @@ +=== tests/cases/compiler/vueLikeDataAndPropsInference2.ts === +interface Instance { + _instanceBrand: never +>_instanceBrand : never +} + +type DataDef = (this: Readonly & Instance) => Data +>DataDef : DataDef +>this : Readonly & Instance + +type PropsDefinition = { +>PropsDefinition : PropsDefinition + + [K in keyof T]: T[K] +} + +interface Options< + Data = object | ((this: Instance) => object), +>this : Instance + + PropsDef = PropsDefinition> + > { + data?: Data +>data : Data + + props?: PropsDef +>props : PropsDef + + watch?: Record> +>watch : Record> +} + +type WatchHandler = (val: T, oldVal: T) => void; +>WatchHandler : WatchHandler +>val : T +>oldVal : T + +type ThisTypedOptions = +>ThisTypedOptions : ThisTypedOptions + + object & + Options, PropsDefinition> & + ThisType & Instance> + +declare function test(fn: ThisTypedOptions): void; +>test : { (fn: ThisTypedOptions): void; (fn: Options object), PropsDefinition>>): void; } +>fn : ThisTypedOptions + +declare function test(fn: Options): void; +>test : { (fn: ThisTypedOptions): void; (fn: Options object), PropsDefinition>>): void; } +>fn : Options object), PropsDefinition>> + +test({ +>test({ props: { foo: '' }, data(): { bar: boolean } { return { bar: true } }, watch: { foo(newVal: string, oldVal: string): void { this.bar = false } }}) : void +>test : { (fn: ThisTypedOptions): void; (fn: Options object), PropsDefinition>>): void; } +>{ props: { foo: '' }, data(): { bar: boolean } { return { bar: true } }, watch: { foo(newVal: string, oldVal: string): void { this.bar = false } }} : { props: { foo: string; }; data(this: Readonly<{ foo: string; }> & Instance): { bar: boolean; }; watch: { foo(newVal: string, oldVal: string): void; }; } + + props: { +>props : { foo: string; } +>{ foo: '' } : { foo: string; } + + foo: '' +>foo : string +>'' : "" + + }, + + data(): { bar: boolean } { +>data : (this: Readonly<{ foo: string; }> & Instance) => { bar: boolean; } +>bar : boolean + + return { +>{ bar: true } : { bar: true; } + + bar: true +>bar : true +>true : true + } + }, + + watch: { +>watch : { foo(newVal: string, oldVal: string): void; } +>{ foo(newVal: string, oldVal: string): void { this.bar = false } } : { foo(newVal: string, oldVal: string): void; } + + foo(newVal: string, oldVal: string): void { +>foo : (newVal: string, oldVal: string) => void +>newVal : string +>oldVal : string + + this.bar = false +>this.bar = false : false +>this.bar : any +>this : any +>bar : any +>false : false + } + } +}) diff --git a/tests/cases/compiler/vueLikeDataAndPropsInference.ts b/tests/cases/compiler/vueLikeDataAndPropsInference.ts new file mode 100644 index 0000000000000..1a227744109b2 --- /dev/null +++ b/tests/cases/compiler/vueLikeDataAndPropsInference.ts @@ -0,0 +1,45 @@ +interface Instance { + _instanceBrand: never +} + +type DataDef = (this: Readonly & Instance) => Data + +type PropsDefinition = { + [K in keyof T]: T[K] +} + +interface Options< + Data = ((this: Instance) => object), + PropsDef = {} + > { + data?: Data + props?: PropsDef + watch?: Record> +} + +type WatchHandler = (val: T, oldVal: T) => void; + +type ThisTypedOptions = + Options, PropsDefinition> & + ThisType & Instance> + +declare function test(fn: ThisTypedOptions): void; +declare function test(fn: Options): void; + +test({ + props: { + foo: '' + }, + + data(): { bar: boolean } { + return { + bar: true + } + }, + + watch: { + foo(newVal: string, oldVal: string): void { + this.bar = false + } + } +}) \ No newline at end of file diff --git a/tests/cases/compiler/vueLikeDataAndPropsInference2.ts b/tests/cases/compiler/vueLikeDataAndPropsInference2.ts new file mode 100644 index 0000000000000..99903e6e37d18 --- /dev/null +++ b/tests/cases/compiler/vueLikeDataAndPropsInference2.ts @@ -0,0 +1,46 @@ +interface Instance { + _instanceBrand: never +} + +type DataDef = (this: Readonly & Instance) => Data + +type PropsDefinition = { + [K in keyof T]: T[K] +} + +interface Options< + Data = object | ((this: Instance) => object), + PropsDef = PropsDefinition> + > { + data?: Data + props?: PropsDef + watch?: Record> +} + +type WatchHandler = (val: T, oldVal: T) => void; + +type ThisTypedOptions = + object & + Options, PropsDefinition> & + ThisType & Instance> + +declare function test(fn: ThisTypedOptions): void; +declare function test(fn: Options): void; + +test({ + props: { + foo: '' + }, + + data(): { bar: boolean } { + return { + bar: true + } + }, + + watch: { + foo(newVal: string, oldVal: string): void { + this.bar = false + } + } +}) \ No newline at end of file diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index 722ebf8053d2b..1bf5836cae524 160000 --- a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +++ b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter @@ -1 +1 @@ -Subproject commit 722ebf8053d2bf82bb66134b21c7e291ccae35c4 +Subproject commit 1bf5836cae5246b89bbf7063c3e84e110222fcdf diff --git a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter index 19c71f2c6a2b8..bfc20b2f17c02 160000 --- a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter +++ b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter @@ -1 +1 @@ -Subproject commit 19c71f2c6a2b874b1b2bb28a8526b19185b8eece +Subproject commit bfc20b2f17c0206105e2cdd42cd35d79dd03a884 diff --git a/tests/cases/user/create-react-app/create-react-app b/tests/cases/user/create-react-app/create-react-app index 6560858398ddc..437b83f0337a5 160000 --- a/tests/cases/user/create-react-app/create-react-app +++ b/tests/cases/user/create-react-app/create-react-app @@ -1 +1 @@ -Subproject commit 6560858398ddc8d1c5b8d7f51929fcb3d9c3055c +Subproject commit 437b83f0337a5d57ce7dd976d2c3b44cb2037e45 diff --git a/tests/cases/user/prettier/prettier b/tests/cases/user/prettier/prettier index 2523a017aad47..2314640485001 160000 --- a/tests/cases/user/prettier/prettier +++ b/tests/cases/user/prettier/prettier @@ -1 +1 @@ -Subproject commit 2523a017aad479b006593e9b380e4e27a7caea3d +Subproject commit 23146404850011972f695fb6bc2b8113c3cffbfc diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer index cba0f98a2ac7e..b6b29502eb6a7 160000 --- a/tests/cases/user/puppeteer/puppeteer +++ b/tests/cases/user/puppeteer/puppeteer @@ -1 +1 @@ -Subproject commit cba0f98a2ac7edd3c2bffd0ac53185877403da6b +Subproject commit b6b29502eb6a75fe3869806f0e7b27195fe51b0d diff --git a/tests/cases/user/webpack/webpack b/tests/cases/user/webpack/webpack index 6d923f638abab..743ae6da9a6fc 160000 --- a/tests/cases/user/webpack/webpack +++ b/tests/cases/user/webpack/webpack @@ -1 +1 @@ -Subproject commit 6d923f638abab6ca5d0263be000a48ef85002fd4 +Subproject commit 743ae6da9a6fc3b459a7ab3bb250fb07d14f9c5d