diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d695daf6ceb1..ae6a012d5ccc6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23904,6 +23904,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && resolved.indexInfos.length === 0 && resolved.properties.length > 0 && every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); } + if (type.flags & TypeFlags.Substitution) { + return isWeakType((type as SubstitutionType).baseType); + } if (type.flags & TypeFlags.Intersection) { return every((type as IntersectionType).types, isWeakType); } @@ -32626,7 +32629,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return true; } } - else if (targetType.flags & TypeFlags.UnionOrIntersection && isExcessPropertyCheckTarget(targetType)) { + if (targetType.flags & TypeFlags.Substitution) { + return isKnownProperty((targetType as SubstitutionType).baseType, name, isComparingJsxAttributes); + } + if (targetType.flags & TypeFlags.UnionOrIntersection && isExcessPropertyCheckTarget(targetType)) { for (const t of (targetType as UnionOrIntersectionType).types) { if (isKnownProperty(t, name, isComparingJsxAttributes)) { return true; @@ -32639,6 +32645,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isExcessPropertyCheckTarget(type: Type): boolean { return !!(type.flags & TypeFlags.Object && !(getObjectFlags(type) & ObjectFlags.ObjectLiteralPatternWithComputedProperties) || type.flags & TypeFlags.NonPrimitive || + type.flags & TypeFlags.Substitution && isExcessPropertyCheckTarget((type as SubstitutionType).baseType) || type.flags & TypeFlags.Union && some((type as UnionType).types, isExcessPropertyCheckTarget) || type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, isExcessPropertyCheckTarget)); } diff --git a/tests/baselines/reference/noInferCommonPropertyCheck1.errors.txt b/tests/baselines/reference/noInferCommonPropertyCheck1.errors.txt new file mode 100644 index 0000000000000..b7f23a4faa315 --- /dev/null +++ b/tests/baselines/reference/noInferCommonPropertyCheck1.errors.txt @@ -0,0 +1,36 @@ +noInferCommonPropertyCheck1.ts(7,20): error TS2559: Type '{ x: string; }' has no properties in common with type 'NoInfer> & { prop?: unknown; }'. +noInferCommonPropertyCheck1.ts(15,33): error TS2559: Type '{ x: string; }' has no properties in common with type 'NoInfer> & NoInfer>'. +noInferCommonPropertyCheck1.ts(23,33): error TS2559: Type '{ x: string; }' has no properties in common with type 'Partial<{ a: unknown; b: unknown; }> & Partial<{ c: unknown; d: unknown; }>'. + + +==== noInferCommonPropertyCheck1.ts (3 errors) ==== + declare const partialObj1: Partial<{ a: unknown; b: unknown }>; + declare const partialObj2: Partial<{ c: unknown; d: unknown }>; + declare const someObj1: { x: string }; + + declare function test1(a: T, b: NoInfer & { prop?: unknown }): void; + + test1(partialObj1, someObj1); + ~~~~~~~~ +!!! error TS2559: Type '{ x: string; }' has no properties in common with type 'NoInfer> & { prop?: unknown; }'. + + declare function test2( + a: T1, + b: T2, + c: NoInfer & NoInfer, + ): void; + + test2(partialObj1, partialObj2, someObj1); + ~~~~~~~~ +!!! error TS2559: Type '{ x: string; }' has no properties in common with type 'NoInfer> & NoInfer>'. + + declare function test3( + a: T1, + b: T2, + c: NoInfer, + ): void; + + test3(partialObj1, partialObj2, someObj1); + ~~~~~~~~ +!!! error TS2559: Type '{ x: string; }' has no properties in common with type 'Partial<{ a: unknown; b: unknown; }> & Partial<{ c: unknown; d: unknown; }>'. + \ No newline at end of file diff --git a/tests/baselines/reference/noInferCommonPropertyCheck1.symbols b/tests/baselines/reference/noInferCommonPropertyCheck1.symbols new file mode 100644 index 0000000000000..e23ba3fe3baf3 --- /dev/null +++ b/tests/baselines/reference/noInferCommonPropertyCheck1.symbols @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/noInferCommonPropertyCheck1.ts] //// + +=== noInferCommonPropertyCheck1.ts === +declare const partialObj1: Partial<{ a: unknown; b: unknown }>; +>partialObj1 : Symbol(partialObj1, Decl(noInferCommonPropertyCheck1.ts, 0, 13)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(noInferCommonPropertyCheck1.ts, 0, 36)) +>b : Symbol(b, Decl(noInferCommonPropertyCheck1.ts, 0, 48)) + +declare const partialObj2: Partial<{ c: unknown; d: unknown }>; +>partialObj2 : Symbol(partialObj2, Decl(noInferCommonPropertyCheck1.ts, 1, 13)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>c : Symbol(c, Decl(noInferCommonPropertyCheck1.ts, 1, 36)) +>d : Symbol(d, Decl(noInferCommonPropertyCheck1.ts, 1, 48)) + +declare const someObj1: { x: string }; +>someObj1 : Symbol(someObj1, Decl(noInferCommonPropertyCheck1.ts, 2, 13)) +>x : Symbol(x, Decl(noInferCommonPropertyCheck1.ts, 2, 25)) + +declare function test1(a: T, b: NoInfer & { prop?: unknown }): void; +>test1 : Symbol(test1, Decl(noInferCommonPropertyCheck1.ts, 2, 38)) +>T : Symbol(T, Decl(noInferCommonPropertyCheck1.ts, 4, 23)) +>a : Symbol(a, Decl(noInferCommonPropertyCheck1.ts, 4, 26)) +>T : Symbol(T, Decl(noInferCommonPropertyCheck1.ts, 4, 23)) +>b : Symbol(b, Decl(noInferCommonPropertyCheck1.ts, 4, 31)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(noInferCommonPropertyCheck1.ts, 4, 23)) +>prop : Symbol(prop, Decl(noInferCommonPropertyCheck1.ts, 4, 49)) + +test1(partialObj1, someObj1); +>test1 : Symbol(test1, Decl(noInferCommonPropertyCheck1.ts, 2, 38)) +>partialObj1 : Symbol(partialObj1, Decl(noInferCommonPropertyCheck1.ts, 0, 13)) +>someObj1 : Symbol(someObj1, Decl(noInferCommonPropertyCheck1.ts, 2, 13)) + +declare function test2( +>test2 : Symbol(test2, Decl(noInferCommonPropertyCheck1.ts, 6, 29)) +>T1 : Symbol(T1, Decl(noInferCommonPropertyCheck1.ts, 8, 23)) +>T2 : Symbol(T2, Decl(noInferCommonPropertyCheck1.ts, 8, 26)) + + a: T1, +>a : Symbol(a, Decl(noInferCommonPropertyCheck1.ts, 8, 31)) +>T1 : Symbol(T1, Decl(noInferCommonPropertyCheck1.ts, 8, 23)) + + b: T2, +>b : Symbol(b, Decl(noInferCommonPropertyCheck1.ts, 9, 8)) +>T2 : Symbol(T2, Decl(noInferCommonPropertyCheck1.ts, 8, 26)) + + c: NoInfer & NoInfer, +>c : Symbol(c, Decl(noInferCommonPropertyCheck1.ts, 10, 8)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T1 : Symbol(T1, Decl(noInferCommonPropertyCheck1.ts, 8, 23)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T2 : Symbol(T2, Decl(noInferCommonPropertyCheck1.ts, 8, 26)) + +): void; + +test2(partialObj1, partialObj2, someObj1); +>test2 : Symbol(test2, Decl(noInferCommonPropertyCheck1.ts, 6, 29)) +>partialObj1 : Symbol(partialObj1, Decl(noInferCommonPropertyCheck1.ts, 0, 13)) +>partialObj2 : Symbol(partialObj2, Decl(noInferCommonPropertyCheck1.ts, 1, 13)) +>someObj1 : Symbol(someObj1, Decl(noInferCommonPropertyCheck1.ts, 2, 13)) + +declare function test3( +>test3 : Symbol(test3, Decl(noInferCommonPropertyCheck1.ts, 14, 42)) +>T1 : Symbol(T1, Decl(noInferCommonPropertyCheck1.ts, 16, 23)) +>T2 : Symbol(T2, Decl(noInferCommonPropertyCheck1.ts, 16, 26)) + + a: T1, +>a : Symbol(a, Decl(noInferCommonPropertyCheck1.ts, 16, 31)) +>T1 : Symbol(T1, Decl(noInferCommonPropertyCheck1.ts, 16, 23)) + + b: T2, +>b : Symbol(b, Decl(noInferCommonPropertyCheck1.ts, 17, 8)) +>T2 : Symbol(T2, Decl(noInferCommonPropertyCheck1.ts, 16, 26)) + + c: NoInfer, +>c : Symbol(c, Decl(noInferCommonPropertyCheck1.ts, 18, 8)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T1 : Symbol(T1, Decl(noInferCommonPropertyCheck1.ts, 16, 23)) +>T2 : Symbol(T2, Decl(noInferCommonPropertyCheck1.ts, 16, 26)) + +): void; + +test3(partialObj1, partialObj2, someObj1); +>test3 : Symbol(test3, Decl(noInferCommonPropertyCheck1.ts, 14, 42)) +>partialObj1 : Symbol(partialObj1, Decl(noInferCommonPropertyCheck1.ts, 0, 13)) +>partialObj2 : Symbol(partialObj2, Decl(noInferCommonPropertyCheck1.ts, 1, 13)) +>someObj1 : Symbol(someObj1, Decl(noInferCommonPropertyCheck1.ts, 2, 13)) + diff --git a/tests/baselines/reference/noInferCommonPropertyCheck1.types b/tests/baselines/reference/noInferCommonPropertyCheck1.types new file mode 100644 index 0000000000000..7097dd67bf98a --- /dev/null +++ b/tests/baselines/reference/noInferCommonPropertyCheck1.types @@ -0,0 +1,71 @@ +//// [tests/cases/compiler/noInferCommonPropertyCheck1.ts] //// + +=== noInferCommonPropertyCheck1.ts === +declare const partialObj1: Partial<{ a: unknown; b: unknown }>; +>partialObj1 : Partial<{ a: unknown; b: unknown; }> +>a : unknown +>b : unknown + +declare const partialObj2: Partial<{ c: unknown; d: unknown }>; +>partialObj2 : Partial<{ c: unknown; d: unknown; }> +>c : unknown +>d : unknown + +declare const someObj1: { x: string }; +>someObj1 : { x: string; } +>x : string + +declare function test1(a: T, b: NoInfer & { prop?: unknown }): void; +>test1 : (a: T, b: NoInfer & { prop?: unknown;}) => void +>a : T +>b : NoInfer & { prop?: unknown; } +>prop : unknown + +test1(partialObj1, someObj1); +>test1(partialObj1, someObj1) : void +>test1 : (a: T, b: NoInfer & { prop?: unknown; }) => void +>partialObj1 : Partial<{ a: unknown; b: unknown; }> +>someObj1 : { x: string; } + +declare function test2( +>test2 : (a: T1, b: T2, c: NoInfer & NoInfer) => void + + a: T1, +>a : T1 + + b: T2, +>b : T2 + + c: NoInfer & NoInfer, +>c : NoInfer & NoInfer + +): void; + +test2(partialObj1, partialObj2, someObj1); +>test2(partialObj1, partialObj2, someObj1) : void +>test2 : (a: T1, b: T2, c: NoInfer & NoInfer) => void +>partialObj1 : Partial<{ a: unknown; b: unknown; }> +>partialObj2 : Partial<{ c: unknown; d: unknown; }> +>someObj1 : { x: string; } + +declare function test3( +>test3 : (a: T1, b: T2, c: NoInfer) => void + + a: T1, +>a : T1 + + b: T2, +>b : T2 + + c: NoInfer, +>c : NoInfer + +): void; + +test3(partialObj1, partialObj2, someObj1); +>test3(partialObj1, partialObj2, someObj1) : void +>test3 : (a: T1, b: T2, c: NoInfer) => void +>partialObj1 : Partial<{ a: unknown; b: unknown; }> +>partialObj2 : Partial<{ c: unknown; d: unknown; }> +>someObj1 : { x: string; } + diff --git a/tests/baselines/reference/noInferUnionExcessPropertyCheck1.errors.txt b/tests/baselines/reference/noInferUnionExcessPropertyCheck1.errors.txt new file mode 100644 index 0000000000000..b5e6542911464 --- /dev/null +++ b/tests/baselines/reference/noInferUnionExcessPropertyCheck1.errors.txt @@ -0,0 +1,36 @@ +noInferUnionExcessPropertyCheck1.ts(7,33): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'NoInfer<{ x: string; }> | (() => NoInfer<{ x: string; }>)'. +noInferUnionExcessPropertyCheck1.ts(15,33): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'NoInfer<{ x: string; }> | NoInfer<() => { x: string; }>'. +noInferUnionExcessPropertyCheck1.ts(23,33): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: string; } | (() => { x: string; })'. + + +==== noInferUnionExcessPropertyCheck1.ts (3 errors) ==== + declare function test1( + a: T, + b: NoInfer | (() => NoInfer), + ): void; + + test1({ x: "foo" }, { x: "bar" }); // no error + test1({ x: "foo" }, { x: "bar", y: 42 }); // epc error + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'NoInfer<{ x: string; }> | (() => NoInfer<{ x: string; }>)'. + + declare function test2( + a: T, + b: NoInfer | NoInfer<() => T>, + ): void; + + test2({ x: "foo" }, { x: "bar" }); // no error + test2({ x: "foo" }, { x: "bar", y: 42 }); // epc error + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'NoInfer<{ x: string; }> | NoInfer<() => { x: string; }>'. + + declare function test3( + a: T, + b: NoInfer T)>, + ): void; + + test3({ x: "foo" }, { x: "bar" }); // no error + test3({ x: "foo" }, { x: "bar", y: 42 }); // epc error + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: string; } | (() => { x: string; })'. + \ No newline at end of file diff --git a/tests/baselines/reference/noInferUnionExcessPropertyCheck1.symbols b/tests/baselines/reference/noInferUnionExcessPropertyCheck1.symbols new file mode 100644 index 0000000000000..b025214a87ca5 --- /dev/null +++ b/tests/baselines/reference/noInferUnionExcessPropertyCheck1.symbols @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/noInferUnionExcessPropertyCheck1.ts] //// + +=== noInferUnionExcessPropertyCheck1.ts === +declare function test1( +>test1 : Symbol(test1, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 0)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 23)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 34)) + + a: T, +>a : Symbol(a, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 48)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 23)) + + b: NoInfer | (() => NoInfer), +>b : Symbol(b, Decl(noInferUnionExcessPropertyCheck1.ts, 1, 7)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 23)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 23)) + +): void; + +test1({ x: "foo" }, { x: "bar" }); // no error +>test1 : Symbol(test1, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 0)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 5, 7)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 5, 21)) + +test1({ x: "foo" }, { x: "bar", y: 42 }); // epc error +>test1 : Symbol(test1, Decl(noInferUnionExcessPropertyCheck1.ts, 0, 0)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 6, 7)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 6, 21)) +>y : Symbol(y, Decl(noInferUnionExcessPropertyCheck1.ts, 6, 31)) + +declare function test2( +>test2 : Symbol(test2, Decl(noInferUnionExcessPropertyCheck1.ts, 6, 41)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 8, 23)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 8, 34)) + + a: T, +>a : Symbol(a, Decl(noInferUnionExcessPropertyCheck1.ts, 8, 48)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 8, 23)) + + b: NoInfer | NoInfer<() => T>, +>b : Symbol(b, Decl(noInferUnionExcessPropertyCheck1.ts, 9, 7)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 8, 23)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 8, 23)) + +): void; + +test2({ x: "foo" }, { x: "bar" }); // no error +>test2 : Symbol(test2, Decl(noInferUnionExcessPropertyCheck1.ts, 6, 41)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 13, 7)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 13, 21)) + +test2({ x: "foo" }, { x: "bar", y: 42 }); // epc error +>test2 : Symbol(test2, Decl(noInferUnionExcessPropertyCheck1.ts, 6, 41)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 14, 7)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 14, 21)) +>y : Symbol(y, Decl(noInferUnionExcessPropertyCheck1.ts, 14, 31)) + +declare function test3( +>test3 : Symbol(test3, Decl(noInferUnionExcessPropertyCheck1.ts, 14, 41)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 16, 23)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 16, 34)) + + a: T, +>a : Symbol(a, Decl(noInferUnionExcessPropertyCheck1.ts, 16, 48)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 16, 23)) + + b: NoInfer T)>, +>b : Symbol(b, Decl(noInferUnionExcessPropertyCheck1.ts, 17, 7)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 16, 23)) +>T : Symbol(T, Decl(noInferUnionExcessPropertyCheck1.ts, 16, 23)) + +): void; + +test3({ x: "foo" }, { x: "bar" }); // no error +>test3 : Symbol(test3, Decl(noInferUnionExcessPropertyCheck1.ts, 14, 41)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 21, 7)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 21, 21)) + +test3({ x: "foo" }, { x: "bar", y: 42 }); // epc error +>test3 : Symbol(test3, Decl(noInferUnionExcessPropertyCheck1.ts, 14, 41)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 22, 7)) +>x : Symbol(x, Decl(noInferUnionExcessPropertyCheck1.ts, 22, 21)) +>y : Symbol(y, Decl(noInferUnionExcessPropertyCheck1.ts, 22, 31)) + diff --git a/tests/baselines/reference/noInferUnionExcessPropertyCheck1.types b/tests/baselines/reference/noInferUnionExcessPropertyCheck1.types new file mode 100644 index 0000000000000..50c0b43aac64e --- /dev/null +++ b/tests/baselines/reference/noInferUnionExcessPropertyCheck1.types @@ -0,0 +1,105 @@ +//// [tests/cases/compiler/noInferUnionExcessPropertyCheck1.ts] //// + +=== noInferUnionExcessPropertyCheck1.ts === +declare function test1( +>test1 : (a: T, b: NoInfer | (() => NoInfer)) => void +>x : string + + a: T, +>a : T + + b: NoInfer | (() => NoInfer), +>b : NoInfer | (() => NoInfer) + +): void; + +test1({ x: "foo" }, { x: "bar" }); // no error +>test1({ x: "foo" }, { x: "bar" }) : void +>test1 : (a: T, b: NoInfer | (() => NoInfer)) => void +>{ x: "foo" } : { x: string; } +>x : string +>"foo" : "foo" +>{ x: "bar" } : { x: string; } +>x : string +>"bar" : "bar" + +test1({ x: "foo" }, { x: "bar", y: 42 }); // epc error +>test1({ x: "foo" }, { x: "bar", y: 42 }) : void +>test1 : (a: T, b: NoInfer | (() => NoInfer)) => void +>{ x: "foo" } : { x: string; } +>x : string +>"foo" : "foo" +>{ x: "bar", y: 42 } : { x: string; y: number; } +>x : string +>"bar" : "bar" +>y : number +>42 : 42 + +declare function test2( +>test2 : (a: T, b: NoInfer | NoInfer<() => T>) => void +>x : string + + a: T, +>a : T + + b: NoInfer | NoInfer<() => T>, +>b : NoInfer | NoInfer<() => T> + +): void; + +test2({ x: "foo" }, { x: "bar" }); // no error +>test2({ x: "foo" }, { x: "bar" }) : void +>test2 : (a: T, b: NoInfer | NoInfer<() => T>) => void +>{ x: "foo" } : { x: string; } +>x : string +>"foo" : "foo" +>{ x: "bar" } : { x: string; } +>x : string +>"bar" : "bar" + +test2({ x: "foo" }, { x: "bar", y: 42 }); // epc error +>test2({ x: "foo" }, { x: "bar", y: 42 }) : void +>test2 : (a: T, b: NoInfer | NoInfer<() => T>) => void +>{ x: "foo" } : { x: string; } +>x : string +>"foo" : "foo" +>{ x: "bar", y: 42 } : { x: string; y: number; } +>x : string +>"bar" : "bar" +>y : number +>42 : 42 + +declare function test3( +>test3 : (a: T, b: NoInfer T)>) => void +>x : string + + a: T, +>a : T + + b: NoInfer T)>, +>b : NoInfer T)> + +): void; + +test3({ x: "foo" }, { x: "bar" }); // no error +>test3({ x: "foo" }, { x: "bar" }) : void +>test3 : (a: T, b: NoInfer T)>) => void +>{ x: "foo" } : { x: string; } +>x : string +>"foo" : "foo" +>{ x: "bar" } : { x: string; } +>x : string +>"bar" : "bar" + +test3({ x: "foo" }, { x: "bar", y: 42 }); // epc error +>test3({ x: "foo" }, { x: "bar", y: 42 }) : void +>test3 : (a: T, b: NoInfer T)>) => void +>{ x: "foo" } : { x: string; } +>x : string +>"foo" : "foo" +>{ x: "bar", y: 42 } : { x: string; y: number; } +>x : string +>"bar" : "bar" +>y : number +>42 : 42 + diff --git a/tests/cases/compiler/noInferCommonPropertyCheck1.ts b/tests/cases/compiler/noInferCommonPropertyCheck1.ts new file mode 100644 index 0000000000000..f78493a9a3c7e --- /dev/null +++ b/tests/cases/compiler/noInferCommonPropertyCheck1.ts @@ -0,0 +1,26 @@ +// @strict: true +// @noEmit: true + +declare const partialObj1: Partial<{ a: unknown; b: unknown }>; +declare const partialObj2: Partial<{ c: unknown; d: unknown }>; +declare const someObj1: { x: string }; + +declare function test1(a: T, b: NoInfer & { prop?: unknown }): void; + +test1(partialObj1, someObj1); + +declare function test2( + a: T1, + b: T2, + c: NoInfer & NoInfer, +): void; + +test2(partialObj1, partialObj2, someObj1); + +declare function test3( + a: T1, + b: T2, + c: NoInfer, +): void; + +test3(partialObj1, partialObj2, someObj1); diff --git a/tests/cases/compiler/noInferUnionExcessPropertyCheck1.ts b/tests/cases/compiler/noInferUnionExcessPropertyCheck1.ts new file mode 100644 index 0000000000000..8067936958ba9 --- /dev/null +++ b/tests/cases/compiler/noInferUnionExcessPropertyCheck1.ts @@ -0,0 +1,26 @@ +// @strict: true +// @noEmit: true + +declare function test1( + a: T, + b: NoInfer | (() => NoInfer), +): void; + +test1({ x: "foo" }, { x: "bar" }); // no error +test1({ x: "foo" }, { x: "bar", y: 42 }); // epc error + +declare function test2( + a: T, + b: NoInfer | NoInfer<() => T>, +): void; + +test2({ x: "foo" }, { x: "bar" }); // no error +test2({ x: "foo" }, { x: "bar", y: 42 }); // epc error + +declare function test3( + a: T, + b: NoInfer T)>, +): void; + +test3({ x: "foo" }, { x: "bar" }); // no error +test3({ x: "foo" }, { x: "bar", y: 42 }); // epc error