From 10a9bb671f35297c24106ca67a20fb4a4012d839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 25 Feb 2023 18:32:18 +0100 Subject: [PATCH 01/13] Infer from filtering mapped types --- src/compiler/checker.ts | 26 ++-- ...dTypeInferFromFilteringNameType.errors.txt | 48 ++++++++ ...ppedTypeInferFromFilteringNameType.symbols | 113 ++++++++++++++++++ ...MappedTypeInferFromFilteringNameType.types | 107 +++++++++++++++++ ...rseMappedTypeInferFromFilteringNameType.ts | 41 +++++++ 5 files changed, 326 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt create mode 100644 tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types create mode 100644 tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index beb75fd16d2dc..2a6fb6abc2d0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13174,8 +13174,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // and T as the template type. const typeParameter = getTypeParameterFromMappedType(type); const constraintType = getConstraintTypeFromMappedType(type); - const nameType = getNameTypeFromMappedType(type.target as MappedType || type); - const isFilteringMappedType = nameType && isTypeAssignableTo(nameType, typeParameter); + const mappedType = (type.target as MappedType) || type; + const nameType = getNameTypeFromMappedType(mappedType); + const shouldLinkPropDeclarations = !nameType || isFilteringMappedType(mappedType); const templateType = getTemplateTypeFromMappedType(type.target as MappedType || type); const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateModifiers = getMappedTypeModifiers(type); @@ -13222,7 +13223,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { prop.links.keyType = keyType; if (modifiersProp) { prop.links.syntheticOrigin = modifiersProp; - prop.declarations = !nameType || isFilteringMappedType ? modifiersProp.declarations : undefined; + prop.declarations = shouldLinkPropDeclarations ? modifiersProp.declarations : undefined; } members.set(propName, prop); } @@ -13355,6 +13356,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } + function isFilteringMappedType(type: MappedType): boolean { + const nameType = getNameTypeFromMappedType(type); + return !!nameType && isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type)); + } + function resolveStructuredTypeMembers(type: StructuredType): ResolvedType { if (!(type as ResolvedType).members) { if (type.flags & TypeFlags.Object) { @@ -17473,8 +17479,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // K is generic and N is assignable to P, instantiate E using a mapper that substitutes the index type for P. // For example, for an index access { [P in K]: Box }[X], we construct the type Box. if (isGenericMappedType(objectType)) { - const nameType = getNameTypeFromMappedType(objectType); - if (!nameType || isTypeAssignableTo(nameType, getTypeParameterFromMappedType(objectType))) { + if (!getNameTypeFromMappedType(objectType) || isFilteringMappedType(objectType)) { return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing)); } } @@ -24730,10 +24735,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const targetNameType = getNameTypeFromMappedType(target); if (sourceNameType && targetNameType) inferFromTypes(sourceNameType, targetNameType); } - if (getObjectFlags(target) & ObjectFlags.Mapped && !(target as MappedType).declaration.nameType) { - const constraintType = getConstraintTypeFromMappedType(target as MappedType); - if (inferToMappedType(source, target as MappedType, constraintType)) { - return; + if (getObjectFlags(target) & ObjectFlags.Mapped) { + const mappedType = target as MappedType; + if (!getNameTypeFromMappedType(mappedType) || isFilteringMappedType(mappedType)) { + const constraintType = getConstraintTypeFromMappedType(mappedType); + if (inferToMappedType(source, mappedType, constraintType)) { + return; + } } } // Infer from the members of source and target only if the two types are possibly related diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt new file mode 100644 index 0000000000000..31edd8eefc0ce --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt @@ -0,0 +1,48 @@ +tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts(34,7): error TS2322: Type '{ last: true; doesntExist: true; }' is not assignable to type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. + Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. + + +==== tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts (1 errors) ==== + declare class User { + public name: string; + public last: string; + public age: number; + } + + type AllowedNeeds = { + [K in keyof T as K & keyof User]: T[K]; + }; + + declare function extend( + input: { + [K in keyof T]: { + needs: AllowedNeeds + compute: (x: Pick) => any; + }; + } + ): T + + const inferred1 = extend({ + fullName: { + needs: { + name: true, + last: true, + }, + compute: (user) => `${user.name} ${user.last}`, + }, + }); + + const inferred2 = extend({ + fullName: { + needs: { + last: true, + doesntExist: true // error + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ last: true; doesntExist: true; }' is not assignable to type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. +!!! error TS2322: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. +!!! related TS6500 tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts:14:7: The expected type comes from property 'needs' which is declared here on type '{ needs: AllowedNeeds<{ last: boolean; doesntExist: boolean; }>; compute: (x: Pick) => any; }' + }, + compute: (user) => {}, + }, + }); + \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols new file mode 100644 index 0000000000000..a61be1a8eca47 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols @@ -0,0 +1,113 @@ +=== tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts === +declare class User { +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) + + public name: string; +>name : Symbol(User.name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 20)) + + public last: string; +>last : Symbol(User.last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 1, 22)) + + public age: number; +>age : Symbol(User.age, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 2, 22)) +} + +type AllowedNeeds = { +>AllowedNeeds : Symbol(AllowedNeeds, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 4, 1)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 6, 18)) + + [K in keyof T as K & keyof User]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 7, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 6, 18)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 7, 3)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 6, 18)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 7, 3)) + +}; + +declare function extend( +>extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 8, 2)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) + + input: { +>input : Symbol(input, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 27)) + + [K in keyof T]: { +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 5)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) + + needs: AllowedNeeds +>needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 21)) +>AllowedNeeds : Symbol(AllowedNeeds, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 4, 1)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 5)) + + compute: (x: Pick) => any; +>compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 13, 31)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 14, 16)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 5)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) + + }; + } +): T +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) + +const inferred1 = extend({ +>inferred1 : Symbol(inferred1, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 19, 5)) +>extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 8, 2)) + + fullName: { +>fullName : Symbol(fullName, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 19, 26)) + + needs: { +>needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 20, 13)) + + name: true, +>name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 21, 12)) + + last: true, +>last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 22, 17)) + + }, + compute: (user) => `${user.name} ${user.last}`, +>compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 24, 6)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 25, 14)) +>user.name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 20)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 25, 14)) +>name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 20)) +>user.last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 1, 22)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 25, 14)) +>last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 1, 22)) + + }, +}); + +const inferred2 = extend({ +>inferred2 : Symbol(inferred2, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 29, 5)) +>extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 8, 2)) + + fullName: { +>fullName : Symbol(fullName, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 29, 26)) + + needs: { +>needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 30, 13)) + + last: true, +>last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 31, 12)) + + doesntExist: true // error +>doesntExist : Symbol(doesntExist, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 32, 17)) + + }, + compute: (user) => {}, +>compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 34, 6)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 35, 14)) + + }, +}); + diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types new file mode 100644 index 0000000000000..1cb6236b30891 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types @@ -0,0 +1,107 @@ +=== tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts === +declare class User { +>User : User + + public name: string; +>name : string + + public last: string; +>last : string + + public age: number; +>age : number +} + +type AllowedNeeds = { +>AllowedNeeds : AllowedNeeds + + [K in keyof T as K & keyof User]: T[K]; +}; + +declare function extend( +>extend : (input: { [K in keyof T]: { needs: AllowedNeeds; compute: (x: Pick) => any; }; }) => T + + input: { +>input : { [K in keyof T]: { needs: AllowedNeeds; compute: (x: Pick) => any; }; } + + [K in keyof T]: { + needs: AllowedNeeds +>needs : AllowedNeeds + + compute: (x: Pick) => any; +>compute : (x: Pick) => any +>x : Pick + + }; + } +): T + +const inferred1 = extend({ +>inferred1 : { fullName: { name: boolean; last: boolean; }; } +>extend({ fullName: { needs: { name: true, last: true, }, compute: (user) => `${user.name} ${user.last}`, },}) : { fullName: { name: boolean; last: boolean; }; } +>extend : (input: { [K in keyof T]: { needs: AllowedNeeds; compute: (x: Pick) => any; }; }) => T +>{ fullName: { needs: { name: true, last: true, }, compute: (user) => `${user.name} ${user.last}`, },} : { fullName: { needs: { name: true; last: true; }; compute: (user: Pick) => string; }; } + + fullName: { +>fullName : { needs: { name: true; last: true; }; compute: (user: Pick) => string; } +>{ needs: { name: true, last: true, }, compute: (user) => `${user.name} ${user.last}`, } : { needs: { name: true; last: true; }; compute: (user: Pick) => string; } + + needs: { +>needs : { name: true; last: true; } +>{ name: true, last: true, } : { name: true; last: true; } + + name: true, +>name : true +>true : true + + last: true, +>last : true +>true : true + + }, + compute: (user) => `${user.name} ${user.last}`, +>compute : (user: Pick) => string +>(user) => `${user.name} ${user.last}` : (user: Pick) => string +>user : Pick +>`${user.name} ${user.last}` : string +>user.name : string +>user : Pick +>name : string +>user.last : string +>user : Pick +>last : string + + }, +}); + +const inferred2 = extend({ +>inferred2 : { fullName: { last: boolean; doesntExist: boolean; }; } +>extend({ fullName: { needs: { last: true, doesntExist: true // error }, compute: (user) => {}, },}) : { fullName: { last: boolean; doesntExist: boolean; }; } +>extend : (input: { [K in keyof T]: { needs: AllowedNeeds; compute: (x: Pick) => any; }; }) => T +>{ fullName: { needs: { last: true, doesntExist: true // error }, compute: (user) => {}, },} : { fullName: { needs: { last: true; doesntExist: boolean; }; compute: (user: Pick) => void; }; } + + fullName: { +>fullName : { needs: { last: true; doesntExist: boolean; }; compute: (user: Pick) => void; } +>{ needs: { last: true, doesntExist: true // error }, compute: (user) => {}, } : { needs: { last: true; doesntExist: boolean; }; compute: (user: Pick) => void; } + + needs: { +>needs : { last: true; doesntExist: boolean; } +>{ last: true, doesntExist: true // error } : { last: true; doesntExist: boolean; } + + last: true, +>last : true +>true : true + + doesntExist: true // error +>doesntExist : boolean +>true : true + + }, + compute: (user) => {}, +>compute : (user: Pick) => void +>(user) => {} : (user: Pick) => void +>user : Pick + + }, +}); + diff --git a/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts b/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts new file mode 100644 index 0000000000000..e1d2b8c21b546 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts @@ -0,0 +1,41 @@ +// @strict: true +// @noEmit: true + +declare class User { + public name: string; + public last: string; + public age: number; +} + +type AllowedNeeds = { + [K in keyof T as K & keyof User]: T[K]; +}; + +declare function extend( + input: { + [K in keyof T]: { + needs: AllowedNeeds + compute: (x: Pick) => any; + }; + } +): T + +const inferred1 = extend({ + fullName: { + needs: { + name: true, + last: true, + }, + compute: (user) => `${user.name} ${user.last}`, + }, +}); + +const inferred2 = extend({ + fullName: { + needs: { + last: true, + doesntExist: true // error + }, + compute: (user) => {}, + }, +}); From cb96fc1d2b7eee15bf1a81df29937bd5a20e90ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 2 Dec 2023 00:23:07 +0100 Subject: [PATCH 02/13] Add more tests --- ...ypeInferFromFilteringNameType1.errors.txt} | 6 +- ...edTypeInferFromFilteringNameType1.symbols} | 104 ++-- ...ppedTypeInferFromFilteringNameType1.types} | 4 +- ...TypeInferFromFilteringNameType2.errors.txt | 196 +++++++ ...pedTypeInferFromFilteringNameType2.symbols | 491 +++++++++++++++++ ...appedTypeInferFromFilteringNameType2.types | 449 ++++++++++++++++ ...appedTypeIntersectionConstraint.errors.txt | 73 +-- ...reverseMappedTypeIntersectionConstraint.js | 49 +- ...seMappedTypeIntersectionConstraint.symbols | 507 +++++++++--------- ...erseMappedTypeIntersectionConstraint.types | 98 ++-- ...eMappedTypeInferFromFilteringNameType1.ts} | 0 ...seMappedTypeInferFromFilteringNameType2.ts | 150 ++++++ ...reverseMappedTypeIntersectionConstraint.ts | 33 +- 13 files changed, 1685 insertions(+), 475 deletions(-) rename tests/baselines/reference/{reverseMappedTypeInferFromFilteringNameType.errors.txt => reverseMappedTypeInferFromFilteringNameType1.errors.txt} (62%) rename tests/baselines/reference/{reverseMappedTypeInferFromFilteringNameType.symbols => reverseMappedTypeInferFromFilteringNameType1.symbols} (58%) rename tests/baselines/reference/{reverseMappedTypeInferFromFilteringNameType.types => reverseMappedTypeInferFromFilteringNameType1.types} (95%) create mode 100644 tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.errors.txt create mode 100644 tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types rename tests/cases/compiler/{reverseMappedTypeInferFromFilteringNameType.ts => reverseMappedTypeInferFromFilteringNameType1.ts} (100%) create mode 100644 tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType2.ts diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt similarity index 62% rename from tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt rename to tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt index 751e37076df46..aa0f075728126 100644 --- a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt @@ -1,7 +1,7 @@ -reverseMappedTypeInferFromFilteringNameType.ts(34,7): error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. +reverseMappedTypeInferFromFilteringNameType1.ts(34,7): error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. -==== reverseMappedTypeInferFromFilteringNameType.ts (1 errors) ==== +==== reverseMappedTypeInferFromFilteringNameType1.ts (1 errors) ==== declare class User { public name: string; public last: string; @@ -38,7 +38,7 @@ reverseMappedTypeInferFromFilteringNameType.ts(34,7): error TS2353: Object liter doesntExist: true // error ~~~~~~~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. -!!! related TS6500 reverseMappedTypeInferFromFilteringNameType.ts:14:7: The expected type comes from property 'needs' which is declared here on type '{ needs: AllowedNeeds<{ last: boolean; doesntExist: boolean; }>; compute: (x: Pick) => any; }' +!!! related TS6500 reverseMappedTypeInferFromFilteringNameType1.ts:14:7: The expected type comes from property 'needs' which is declared here on type '{ needs: AllowedNeeds<{ last: boolean; doesntExist: boolean; }>; compute: (x: Pick) => any; }' }, compute: (user) => {}, }, diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.symbols similarity index 58% rename from tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols rename to tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.symbols index 32baf55afa297..8f886e4f72990 100644 --- a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.symbols +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.symbols @@ -1,114 +1,114 @@ -//// [tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts] //// +//// [tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType1.ts] //// -=== reverseMappedTypeInferFromFilteringNameType.ts === +=== reverseMappedTypeInferFromFilteringNameType1.ts === declare class User { ->User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 0)) public name: string; ->name : Symbol(User.name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 20)) +>name : Symbol(User.name, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 20)) public last: string; ->last : Symbol(User.last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 1, 22)) +>last : Symbol(User.last, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 1, 22)) public age: number; ->age : Symbol(User.age, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 2, 22)) +>age : Symbol(User.age, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 2, 22)) } type AllowedNeeds = { ->AllowedNeeds : Symbol(AllowedNeeds, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 4, 1)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 6, 18)) +>AllowedNeeds : Symbol(AllowedNeeds, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 4, 1)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 6, 18)) [K in keyof T as K & keyof User]: T[K]; ->K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 7, 3)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 6, 18)) ->K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 7, 3)) ->User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 6, 18)) ->K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 7, 3)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 7, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 6, 18)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 7, 3)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 6, 18)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 7, 3)) }; declare function extend( ->extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 8, 2)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) +>extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 8, 2)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 10, 24)) input: { ->input : Symbol(input, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 27)) +>input : Symbol(input, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 10, 27)) [K in keyof T]: { ->K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 5)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 12, 5)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 10, 24)) needs: AllowedNeeds ->needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 21)) ->AllowedNeeds : Symbol(AllowedNeeds, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 4, 1)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) ->K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 5)) +>needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 12, 21)) +>AllowedNeeds : Symbol(AllowedNeeds, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 4, 1)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 10, 24)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 12, 5)) compute: (x: Pick) => any; ->compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 13, 31)) ->x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 14, 16)) +>compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 13, 31)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 14, 16)) >Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) ->User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) ->K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 12, 5)) ->User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 0)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 10, 24)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 12, 5)) +>User : Symbol(User, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 0)) }; } ): T ->T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 10, 24)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 10, 24)) const inferred1 = extend({ ->inferred1 : Symbol(inferred1, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 19, 5)) ->extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 8, 2)) +>inferred1 : Symbol(inferred1, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 19, 5)) +>extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 8, 2)) fullName: { ->fullName : Symbol(fullName, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 19, 26)) +>fullName : Symbol(fullName, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 19, 26)) needs: { ->needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 20, 13)) +>needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 20, 13)) name: true, ->name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 21, 12)) +>name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 21, 12)) last: true, ->last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 22, 17)) +>last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 22, 17)) }, compute: (user) => `${user.name} ${user.last}`, ->compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 24, 6)) ->user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 25, 14)) ->user.name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 20)) ->user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 25, 14)) ->name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 0, 20)) ->user.last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 1, 22)) ->user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 25, 14)) ->last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 1, 22)) +>compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 24, 6)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 25, 14)) +>user.name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 20)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 25, 14)) +>name : Symbol(name, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 0, 20)) +>user.last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 1, 22)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 25, 14)) +>last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 1, 22)) }, }); const inferred2 = extend({ ->inferred2 : Symbol(inferred2, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 29, 5)) ->extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 8, 2)) +>inferred2 : Symbol(inferred2, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 29, 5)) +>extend : Symbol(extend, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 8, 2)) fullName: { ->fullName : Symbol(fullName, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 29, 26)) +>fullName : Symbol(fullName, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 29, 26)) needs: { ->needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 30, 13)) +>needs : Symbol(needs, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 30, 13)) last: true, ->last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 31, 12)) +>last : Symbol(last, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 31, 12)) doesntExist: true // error ->doesntExist : Symbol(doesntExist, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 32, 17)) +>doesntExist : Symbol(doesntExist, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 32, 17)) }, compute: (user) => {}, ->compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 34, 6)) ->user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType.ts, 35, 14)) +>compute : Symbol(compute, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 34, 6)) +>user : Symbol(user, Decl(reverseMappedTypeInferFromFilteringNameType1.ts, 35, 14)) }, }); diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types similarity index 95% rename from tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types rename to tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types index 1a3aefabcdc97..6f512c87462e5 100644 --- a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType.types +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts] //// +//// [tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType1.ts] //// -=== reverseMappedTypeInferFromFilteringNameType.ts === +=== reverseMappedTypeInferFromFilteringNameType1.ts === declare class User { >User : User diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.errors.txt b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.errors.txt new file mode 100644 index 0000000000000..0cab58fe12be9 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.errors.txt @@ -0,0 +1,196 @@ +reverseMappedTypeInferFromFilteringNameType2.ts(18,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +reverseMappedTypeInferFromFilteringNameType2.ts(30,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(40,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(53,5): error TS2322: Type '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeInferFromFilteringNameType2.ts(56,64): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(63,5): error TS2322: Type '{ [K in keyof T as K & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. + Type '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeInferFromFilteringNameType2.ts(66,68): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(75,26): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(83,26): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(85,36): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(96,68): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(139,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ readonly types: { actors: { src: "str"; logic: () => Promise; }; }; readonly invoke: { readonly src: "str"; }; }'. +reverseMappedTypeInferFromFilteringNameType2.ts(145,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ readonly invoke: { readonly src: "whatever"; }; }'. + + +==== reverseMappedTypeInferFromFilteringNameType2.ts (13 errors) ==== + type StateConfig = { + entry?: TAction; + states?: Record>; + }; + declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string + ? TConfig["entry"] + : string, + >(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K] }): [ + TAction, + TConfig, + ]; + const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + ~~~~~ +!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. +!!! related TS6500 reverseMappedTypeInferFromFilteringNameType2.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' + }, + }, + extra: 12, + }); + const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. + }); + + const checkType = + () => + (value: { [K in keyof U as K & keyof T]: U[K] }) => + value; + const checked = checkType<{ x: number; y: string }>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); + + interface Stuff { + field: number; + anotherField: string; + } + function doStuffWithStuff(s: { + [K in keyof T as K & keyof Stuff]: T[K]; + }): T { + if (Math.random() > 0.5) { + return s as T; + } else { + return s; + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + const stuff1 = doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }); + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + function doStuffWithStuffArr( + arr: { [K in keyof T as K & keyof Stuff]: T[K] }[], + ): T[] { + if (Math.random() > 0.5) { + return arr as T[]; + } else { + return arr; + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T as K & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +!!! error TS2322: Type '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T as K & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + const stuff2 = doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]); + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + + type XNumber = { x: number }; + declare function foo(props: { + [K in keyof T as K & keyof XNumber]: T[K]; + }): T; + function bar(props: { x: number; y: string }) { + return foo(props); // no error because lack of excess property check by design + } + const foo1 = foo({ x: 1, y: "foo" }); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + const foo2 = foo({ ...{ x: 1, y: "foo" } }); // no error because lack of excess property check by design + + type NoErrWithOptProps = { x: number; y?: string }; + declare function baz(props: { + [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; + }): T; + const baz1 = baz({ x: 1 }); + const baz2 = baz({ x: 1, z: 123 }); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. + const baz3 = baz({ x: 1, y: "foo" }); + const baz4 = baz({ x: 1, y: "foo", z: 123 }); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. + + interface WithNestedProp { + prop: string; + nested: { + prop: string; + }; + } + declare function withNestedProp(props: { + [K in keyof T as K & keyof WithNestedProp]: T[K]; + }): T; + const wnp = withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }); + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. + + type IsLiteralString = string extends T ? false : true; + interface ProvidedActor { + src: string; + logic: () => Promise; + } + type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; + } + declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { + types: { actors: ProvidedActor }; + } + ? TConfig["types"]["actors"] + : ProvidedActor, + >(config: { + [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; + }): TConfig; + const child = () => Promise.resolve("foo"); + const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ readonly types: { actors: { src: "str"; logic: () => Promise; }; }; readonly invoke: { readonly src: "str"; }; }'. + }); + const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ readonly invoke: { readonly src: "whatever"; }; }'. + }); + \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.symbols b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.symbols new file mode 100644 index 0000000000000..944179ae40452 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.symbols @@ -0,0 +1,491 @@ +//// [tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType2.ts] //// + +=== reverseMappedTypeInferFromFilteringNameType2.ts === +type StateConfig = { +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 17)) + + entry?: TAction; +>entry : Symbol(entry, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 44)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 17)) + + states?: Record>; +>states : Symbol(states, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 1, 18)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 17)) + +}; +declare function createMachine< +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 3, 2)) + + TConfig extends StateConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 4, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 5, 39)) + + TAction extends string = TConfig["entry"] extends string +>TAction : Symbol(TAction, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 5, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 4, 31)) + + ? TConfig["entry"] +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 4, 31)) + + : string, +>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K] }): [ +>config : Symbol(config, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 9, 2)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 9, 13)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 4, 31)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 9, 13)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 0, 0)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 4, 31)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 9, 13)) + + TAction, +>TAction : Symbol(TAction, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 5, 39)) + + TConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 4, 31)) + +]; +const inferredParams1 = createMachine({ +>inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 13, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 3, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 13, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 14, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 15, 11)) + + entry: "bar", +>entry : Symbol(entry, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 16, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 19, 4)) + +}); +const inferredParams2 = createMachine({ +>inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 22, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 3, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 22, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 23, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 24, 11)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 25, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 28, 4)) + +}); + +const checkType = +>checkType : Symbol(checkType, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 32, 5)) + + () => +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 33, 3)) + + (value: { [K in keyof U as K & keyof T]: U[K] }) => +>U : Symbol(U, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 33, 3)) +>value : Symbol(value, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 16)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 26)) +>U : Symbol(U, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 3)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 26)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 33, 3)) +>U : Symbol(U, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 3)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 26)) + + value; +>value : Symbol(value, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 34, 16)) + +const checked = checkType<{ x: number; y: string }>()({ +>checked : Symbol(checked, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 36, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 32, 5)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 36, 27)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 36, 38)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 36, 55)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 37, 17)) + + z: "z", // undesirable property z is *not* allowed +>z : Symbol(z, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 38, 9)) + +}); + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 40, 3)) + + field: number; +>field : Symbol(Stuff.field, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 42, 17)) + + anotherField: string; +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 43, 16)) +} +function doStuffWithStuff(s: { +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 45, 1)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 40, 3)) +>s : Symbol(s, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 43)) + + [K in keyof T as K & keyof Stuff]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 47, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 26)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 47, 3)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 40, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 26)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 47, 3)) + +}): T { +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 26)) + + if (Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return s as T; +>s : Symbol(s, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 43)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 26)) + + } else { + return s; +>s : Symbol(s, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 46, 43)) + } +} +const stuff1 = doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }); +>stuff1 : Symbol(stuff1, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 55, 5)) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 45, 1)) +>field : Symbol(field, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 55, 33)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 55, 43)) +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 55, 62)) + +function doStuffWithStuffArr( +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 55, 77)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 40, 3)) + + arr: { [K in keyof T as K & keyof Stuff]: T[K] }[], +>arr : Symbol(arr, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 46)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 57, 10)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 29)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 57, 10)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 40, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 29)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 57, 10)) + +): T[] { +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 29)) + + if (Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return arr as T[]; +>arr : Symbol(arr, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 46)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 29)) + + } else { + return arr; +>arr : Symbol(arr, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 56, 46)) + } +} +const stuff2 = doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]); +>stuff2 : Symbol(stuff2, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 5)) +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 55, 77)) +>field : Symbol(field, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 37)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 47)) +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 66)) + +type XNumber = { x: number }; +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 82)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 67, 16)) + +declare function foo(props: { +>foo : Symbol(foo, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 67, 29)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 68, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 82)) +>props : Symbol(props, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 68, 40)) + + [K in keyof T as K & keyof XNumber]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 69, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 68, 21)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 69, 3)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 65, 82)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 68, 21)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 69, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 68, 21)) + +function bar(props: { x: number; y: string }) { +>bar : Symbol(bar, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 70, 6)) +>props : Symbol(props, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 71, 13)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 71, 21)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 71, 32)) + + return foo(props); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 67, 29)) +>props : Symbol(props, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 71, 13)) +} +const foo1 = foo({ x: 1, y: "foo" }); +>foo1 : Symbol(foo1, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 74, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 67, 29)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 74, 18)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 74, 24)) + +const foo2 = foo({ ...{ x: 1, y: "foo" } }); // no error because lack of excess property check by design +>foo2 : Symbol(foo2, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 75, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 67, 29)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 75, 23)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 75, 29)) + +type NoErrWithOptProps = { x: number; y?: string }; +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 75, 44)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 26)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 37)) + +declare function baz(props: { +>baz : Symbol(baz, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 51)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 78, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 75, 44)) +>props : Symbol(props, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 78, 50)) + + [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 79, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 78, 21)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 79, 3)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 75, 44)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 78, 21)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 79, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 78, 21)) + +const baz1 = baz({ x: 1 }); +>baz1 : Symbol(baz1, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 81, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 51)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 81, 18)) + +const baz2 = baz({ x: 1, z: 123 }); +>baz2 : Symbol(baz2, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 82, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 51)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 82, 18)) +>z : Symbol(z, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 82, 24)) + +const baz3 = baz({ x: 1, y: "foo" }); +>baz3 : Symbol(baz3, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 83, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 51)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 83, 18)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 83, 24)) + +const baz4 = baz({ x: 1, y: "foo", z: 123 }); +>baz4 : Symbol(baz4, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 77, 51)) +>x : Symbol(x, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 18)) +>y : Symbol(y, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 24)) +>z : Symbol(z, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 34)) + +interface WithNestedProp { +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 45)) + + prop: string; +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 86, 26)) + + nested: { +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 87, 15)) + + prop: string; +>prop : Symbol(prop, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 88, 11)) + + }; +} +declare function withNestedProp(props: { +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 91, 1)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 92, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 45)) +>props : Symbol(props, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 92, 58)) + + [K in keyof T as K & keyof WithNestedProp]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 93, 3)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 92, 32)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 93, 3)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 84, 45)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 92, 32)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 93, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 92, 32)) + +const wnp = withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }); +>wnp : Symbol(wnp, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 91, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 41)) +>prop : Symbol(prop, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 51)) +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 66)) + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 80)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 21)) +>T : Symbol(T, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 21)) + +interface ProvidedActor { +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 73)) + + src: string; +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 98, 25)) + + logic: () => Promise; +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 99, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +} +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 101, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 102, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 102, 22)) +>src : Symbol(src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 102, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 102, 59)) + + ? { + src: TSrc; +>src : Symbol(src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 103, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 102, 59)) + } + : never; +interface MachineConfig { +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 106, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 107, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 73)) + + types?: { +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 107, 55)) + + actors?: TActor; +>actors : Symbol(actors, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 108, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 107, 24)) + + }; + invoke: IsLiteralString extends true +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 110, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 95, 80)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 107, 24)) + + ? DistributeActors +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 101, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 107, 24)) + + : { + src: string; +>src : Symbol(src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 113, 7)) + + }; +} +declare function createXMachine< +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 116, 1)) + + const TConfig extends MachineConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 117, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 106, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 118, 46)) + + TActor extends ProvidedActor = TConfig extends { +>TActor : Symbol(TActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 118, 46)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 73)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 117, 32)) + + types: { actors: ProvidedActor }; +>types : Symbol(types, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 119, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 120, 12)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 73)) + } + ? TConfig["types"]["actors"] +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 117, 32)) + + : ProvidedActor, +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 97, 73)) + +>(config: { +>config : Symbol(config, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 124, 2)) + + [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 125, 3)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 117, 32)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 125, 3)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 106, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 117, 32)) +>K : Symbol(K, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 125, 3)) + +}): TConfig; +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 117, 32)) + +const child = () => Promise.resolve("foo"); +>child : Symbol(child, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 127, 5)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) + +const config = createXMachine({ +>config : Symbol(config, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 128, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 116, 1)) + + types: {} as { +>types : Symbol(types, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 128, 31)) + + actors: { +>actors : Symbol(actors, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 129, 16)) + + src: "str"; +>src : Symbol(src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 130, 13)) + + logic: typeof child; +>logic : Symbol(logic, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 131, 17)) +>child : Symbol(child, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 127, 5)) + + }; + }, + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 134, 4)) + + src: "str", +>src : Symbol(src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 135, 11)) + + }, + extra: 10, +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 137, 4)) + +}); +const config2 = createXMachine({ +>config2 : Symbol(config2, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 140, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 116, 1)) + + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 140, 32)) + + src: "whatever", +>src : Symbol(src, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 141, 11)) + + }, + extra: 10, +>extra : Symbol(extra, Decl(reverseMappedTypeInferFromFilteringNameType2.ts, 143, 4)) + +}); + diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types new file mode 100644 index 0000000000000..c1834b72ce0bb --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types @@ -0,0 +1,449 @@ +//// [tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType2.ts] //// + +=== reverseMappedTypeInferFromFilteringNameType2.ts === +type StateConfig = { +>StateConfig : StateConfig + + entry?: TAction; +>entry : TAction | undefined + + states?: Record>; +>states : Record> | undefined + +}; +declare function createMachine< +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K]; }) => [ TAction, TConfig] + + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string + ? TConfig["entry"] + : string, +>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K] }): [ +>config : { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K]; } + + TAction, + TConfig, +]; +const inferredParams1 = createMachine({ +>inferredParams1 : ["foo", StateConfig<"foo">] +>createMachine({ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,}) : ["foo", StateConfig<"foo">] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "bar"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "bar"; }; } +>{ a: { entry: "bar", }, } : { a: { entry: "bar"; }; } + + a: { +>a : { entry: "bar"; } +>{ entry: "bar", } : { entry: "bar"; } + + entry: "bar", +>entry : "bar" +>"bar" : "bar" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); +const inferredParams2 = createMachine({ +>inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] +>createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "foo"; }; } +>{ a: { entry: "foo", }, } : { a: { entry: "foo"; }; } + + a: { +>a : { entry: "foo"; } +>{ entry: "foo", } : { entry: "foo"; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); + +const checkType = +>checkType : () => (value: { [K in keyof U as K & keyof T]: U[K]; }) => { [K in keyof U as K & keyof T]: U[K]; } + + () => +>() => (value: { [K in keyof U as K & keyof T]: U[K] }) => value : () => (value: { [K in keyof U as K & keyof T]: U[K]; }) => { [K in keyof U as K & keyof T]: U[K]; } + + (value: { [K in keyof U as K & keyof T]: U[K] }) => +>(value: { [K in keyof U as K & keyof T]: U[K] }) => value : (value: { [K in keyof U as K & keyof T]: U[K]; }) => { [K in keyof U as K & keyof T]: U[K]; } +>value : { [K in keyof U as K & keyof T]: U[K]; } + + value; +>value : { [K in keyof U as K & keyof T]: U[K]; } + +const checked = checkType<{ x: number; y: string }>()({ +>checked : { x: number; y: "y"; } +>checkType<{ x: number; y: string }>()({ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed}) : { x: number; y: "y"; } +>checkType<{ x: number; y: string }>() : (value: { [K in keyof U as K & ("y" | "x")]: U[K]; }) => { [K in keyof U as K & ("y" | "x")]: U[K]; } +>checkType : () => (value: { [K in keyof U as K & keyof T]: U[K]; }) => { [K in keyof U as K & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", // undesirable property z is *not* allowed +>z : string +>"z" : "z" + +}); + +interface Stuff { + field: number; +>field : number + + anotherField: string; +>anotherField : string +} +function doStuffWithStuff(s: { +>doStuffWithStuff : (s: { [K in keyof T as K & keyof Stuff]: T[K]; }) => T +>s : { [K in keyof T as K & keyof Stuff]: T[K]; } + + [K in keyof T as K & keyof Stuff]: T[K]; +}): T { + if (Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return s as T; +>s as T : T +>s : { [K in keyof T as K & keyof Stuff]: T[K]; } + + } else { + return s; +>s : { [K in keyof T as K & keyof Stuff]: T[K]; } + } +} +const stuff1 = doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }); +>stuff1 : { field: 1; anotherField: "a"; extra: number; } +>doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }) : { field: 1; anotherField: "a"; extra: number; } +>doStuffWithStuff : (s: { [K in keyof T as K & keyof Stuff]: T[K]; }) => T +>{ field: 1, anotherField: "a", extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>"a" : "a" +>extra : number +>123 : 123 + +function doStuffWithStuffArr( +>doStuffWithStuffArr : (arr: { [K in keyof T as K & keyof Stuff]: T[K]; }[]) => T[] + + arr: { [K in keyof T as K & keyof Stuff]: T[K] }[], +>arr : { [K in keyof T as K & keyof Stuff]: T[K]; }[] + +): T[] { + if (Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return arr as T[]; +>arr as T[] : T[] +>arr : { [K in keyof T as K & keyof Stuff]: T[K]; }[] + + } else { + return arr; +>arr : { [K in keyof T as K & keyof Stuff]: T[K]; }[] + } +} +const stuff2 = doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]); +>stuff2 : { field: 1; anotherField: "a"; extra: number; }[] +>doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]) : { field: 1; anotherField: "a"; extra: number; }[] +>doStuffWithStuffArr : (arr: { [K in keyof T as K & keyof Stuff]: T[K]; }[]) => T[] +>[{ field: 1, anotherField: "a", extra: 123 }] : { field: 1; anotherField: "a"; extra: number; }[] +>{ field: 1, anotherField: "a", extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>"a" : "a" +>extra : number +>123 : 123 + +type XNumber = { x: number }; +>XNumber : { x: number; } +>x : number + +declare function foo(props: { +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>props : { [K in keyof T as K & "x"]: T[K]; } + + [K in keyof T as K & keyof XNumber]: T[K]; +}): T; +function bar(props: { x: number; y: string }) { +>bar : (props: { x: number; y: string;}) => { x: number; y: string; } +>props : { x: number; y: string; } +>x : number +>y : string + + return foo(props); // no error because lack of excess property check by design +>foo(props) : { x: number; y: string; } +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>props : { x: number; y: string; } +} +const foo1 = foo({ x: 1, y: "foo" }); +>foo1 : { x: 1; y: string; } +>foo({ x: 1, y: "foo" }) : { x: 1; y: string; } +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>{ x: 1, y: "foo" } : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>"foo" : "foo" + +const foo2 = foo({ ...{ x: 1, y: "foo" } }); // no error because lack of excess property check by design +>foo2 : { x: 1; y: string; } +>foo({ ...{ x: 1, y: "foo" } }) : { x: 1; y: string; } +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>{ ...{ x: 1, y: "foo" } } : { x: 1; y: string; } +>{ x: 1, y: "foo" } : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>"foo" : "foo" + +type NoErrWithOptProps = { x: number; y?: string }; +>NoErrWithOptProps : { x: number; y?: string | undefined; } +>x : number +>y : string | undefined + +declare function baz(props: { +>baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T +>props : { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; } + + [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; +}): T; +const baz1 = baz({ x: 1 }); +>baz1 : { x: 1; } +>baz({ x: 1 }) : { x: 1; } +>baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T +>{ x: 1 } : { x: 1; } +>x : 1 +>1 : 1 + +const baz2 = baz({ x: 1, z: 123 }); +>baz2 : { x: 1; z: number; } +>baz({ x: 1, z: 123 }) : { x: 1; z: number; } +>baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T +>{ x: 1, z: 123 } : { x: 1; z: number; } +>x : 1 +>1 : 1 +>z : number +>123 : 123 + +const baz3 = baz({ x: 1, y: "foo" }); +>baz3 : { x: 1; y: "foo"; } +>baz({ x: 1, y: "foo" }) : { x: 1; y: "foo"; } +>baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T +>{ x: 1, y: "foo" } : { x: 1; y: "foo"; } +>x : 1 +>1 : 1 +>y : "foo" +>"foo" : "foo" + +const baz4 = baz({ x: 1, y: "foo", z: 123 }); +>baz4 : { x: 1; y: "foo"; z: number; } +>baz({ x: 1, y: "foo", z: 123 }) : { x: 1; y: "foo"; z: number; } +>baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T +>{ x: 1, y: "foo", z: 123 } : { x: 1; y: "foo"; z: number; } +>x : 1 +>1 : 1 +>y : "foo" +>"foo" : "foo" +>z : number +>123 : 123 + +interface WithNestedProp { + prop: string; +>prop : string + + nested: { +>nested : { prop: string; } + + prop: string; +>prop : string + + }; +} +declare function withNestedProp(props: { +>withNestedProp : (props: { [K in keyof T as K & keyof WithNestedProp]: T[K]; }) => T +>props : { [K in keyof T as K & keyof WithNestedProp]: T[K]; } + + [K in keyof T as K & keyof WithNestedProp]: T[K]; +}): T; +const wnp = withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }); +>wnp : { prop: "foo"; nested: { prop: string; }; extra: number; } +>withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; extra: number; } +>withNestedProp : (props: { [K in keyof T as K & keyof WithNestedProp]: T[K]; }) => T +>{ prop: "foo", nested: { prop: "bar" }, extra: 10 } : { prop: "foo"; nested: { prop: string; }; extra: number; } +>prop : "foo" +>"foo" : "foo" +>nested : { prop: string; } +>{ prop: "bar" } : { prop: string; } +>prop : string +>"bar" : "bar" +>extra : number +>10 : 10 + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : IsLiteralString +>false : false +>true : true + +interface ProvidedActor { + src: string; +>src : string + + logic: () => Promise; +>logic : () => Promise +} +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : DistributeActors +>src : TSrc + + ? { + src: TSrc; +>src : TSrc + } + : never; +interface MachineConfig { + types?: { +>types : { actors?: TActor | undefined; } | undefined + + actors?: TActor; +>actors : TActor | undefined + + }; + invoke: IsLiteralString extends true +>invoke : IsLiteralString extends true ? DistributeActors : { src: string; } +>true : true + + ? DistributeActors + : { + src: string; +>src : string + + }; +} +declare function createXMachine< +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; }) => TConfig + + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { + types: { actors: ProvidedActor }; +>types : { actors: ProvidedActor; } +>actors : ProvidedActor + } + ? TConfig["types"]["actors"] + : ProvidedActor, +>(config: { +>config : { [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; } + + [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; +}): TConfig; +const child = () => Promise.resolve("foo"); +>child : () => Promise +>() => Promise.resolve("foo") : () => Promise +>Promise.resolve("foo") : Promise +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } +>Promise : PromiseConstructor +>resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } +>"foo" : "foo" + +const config = createXMachine({ +>config : { readonly types: { actors: { src: "str"; logic: typeof child;}; }; readonly invoke: { readonly src: "str"; }; readonly extra: 10; } +>createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10,}) : { readonly types: { actors: { src: "str"; logic: typeof child;}; }; readonly invoke: { readonly src: "str"; }; readonly extra: 10; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; }) => TConfig +>{ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10,} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } + + types: {} as { +>types : { actors: { src: "str"; logic: typeof child;}; } +>{} as { actors: { src: "str"; logic: typeof child; }; } : { actors: { src: "str"; logic: typeof child;}; } +>{} : {} + + actors: { +>actors : { src: "str"; logic: typeof child; } + + src: "str"; +>src : "str" + + logic: typeof child; +>logic : () => Promise +>child : () => Promise + + }; + }, + invoke: { +>invoke : { src: "str"; } +>{ src: "str", } : { src: "str"; } + + src: "str", +>src : "str" +>"str" : "str" + + }, + extra: 10, +>extra : number +>10 : 10 + +}); +const config2 = createXMachine({ +>config2 : { readonly invoke: { readonly src: "whatever"; }; readonly extra: 10; } +>createXMachine({ invoke: { src: "whatever", }, extra: 10,}) : { readonly invoke: { readonly src: "whatever"; }; readonly extra: 10; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; }) => TConfig +>{ invoke: { src: "whatever", }, extra: 10,} : { invoke: { src: "whatever"; }; extra: number; } + + invoke: { +>invoke : { src: "whatever"; } +>{ src: "whatever", } : { src: "whatever"; } + + src: "whatever", +>src : "whatever" +>"whatever" : "whatever" + + }, + extra: 10, +>extra : number +>10 : 10 + +}); + diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt index ec7eab991b0ed..db13e745a1600 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt @@ -1,32 +1,27 @@ -reverseMappedTypeIntersectionConstraint.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. -reverseMappedTypeIntersectionConstraint.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. -reverseMappedTypeIntersectionConstraint.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -reverseMappedTypeIntersectionConstraint.ts(59,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +reverseMappedTypeIntersectionConstraint.ts(15,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +reverseMappedTypeIntersectionConstraint.ts(28,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +reverseMappedTypeIntersectionConstraint.ts(39,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeIntersectionConstraint.ts(53,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeIntersectionConstraint.ts(63,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeIntersectionConstraint.ts(69,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +reverseMappedTypeIntersectionConstraint.ts(57,64): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(63,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeIntersectionConstraint.ts(74,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeIntersectionConstraint.ts(87,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseMappedTypeIntersectionConstraint.ts(98,12): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. -reverseMappedTypeIntersectionConstraint.ts(100,22): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. -reverseMappedTypeIntersectionConstraint.ts(113,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. -reverseMappedTypeIntersectionConstraint.ts(152,21): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. -reverseMappedTypeIntersectionConstraint.ts(164,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. -reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(68,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(81,25): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(92,25): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(94,35): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeIntersectionConstraint.ts(107,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeIntersectionConstraint.ts(152,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(159,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. -==== reverseMappedTypeIntersectionConstraint.ts (14 errors) ==== +==== reverseMappedTypeIntersectionConstraint.ts (13 errors) ==== type StateConfig = { entry?: TAction states?: Record>; }; - type StateSchema = { - states?: Record; - }; - declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, @@ -70,8 +65,6 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. }); - checked; - // ----------------------------------------------------------------------------------------- interface Stuff { @@ -90,8 +83,8 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal } } - doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - ~~~~~ + const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { @@ -106,7 +99,7 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal } } - doStuffWithStuffArr([ + const stuff2 = doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. @@ -116,31 +109,31 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal type XNumber = { x: number } - declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; + declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; function bar(props: {x: number, y: string}) { return foo(props); // no error because lack of excess property check by design } - foo({x: 1, y: 'foo'}); - ~ + const foo1 = foo({x: 1, y: 'foo'}); + ~ !!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. - foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } - declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; + declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; - baz({x: 1}); - baz({x: 1, z: 123}); - ~ + const baz1 = baz({x: 1}); + const baz2 = baz({x: 1, z: 123}); + ~ !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. - baz({x: 1, y: 'foo'}); - baz({x: 1, y: 'foo', z: 123}); - ~ + const baz3 = baz({x: 1, y: 'foo'}); + const baz4 = baz({x: 1, y: 'foo', z: 123}); + ~ !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. // ----------------------------------------------------------------------------------------- @@ -162,8 +155,6 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal type IsLiteralString = string extends T ? false : true; - type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } - interface ProvidedActor { src: string; logic: () => Promise; @@ -186,18 +177,12 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal }; } - type NoExtra = { - [K in keyof T]: K extends keyof MachineConfig ? T[K] : never - } - declare function createXMachine< const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; const child = () => Promise.resolve("foo"); - ~~~~~~~ -!!! error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. const config = createXMachine({ types: {} as { @@ -211,7 +196,7 @@ reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal }, extra: 10 ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. }); const config2 = createXMachine({ diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js index a68576c793bf8..c97a340c71830 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js @@ -6,10 +6,6 @@ type StateConfig = { states?: Record>; }; -type StateSchema = { - states?: Record; -}; - declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, @@ -46,8 +42,6 @@ const checked = checkType<{x: number, y: string}>()({ z: "z", // undesirable property z is *not* allowed }); -checked; - // ----------------------------------------------------------------------------------------- interface Stuff { @@ -63,7 +57,7 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } } -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { if(Math.random() > 0.5) { @@ -73,7 +67,7 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } } -doStuffWithStuffArr([ +const stuff2 = doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ]) @@ -81,26 +75,26 @@ doStuffWithStuffArr([ type XNumber = { x: number } -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; function bar(props: {x: number, y: string}) { return foo(props); // no error because lack of excess property check by design } -foo({x: 1, y: 'foo'}); +const foo1 = foo({x: 1, y: 'foo'}); -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; -baz({x: 1}); -baz({x: 1, z: 123}); -baz({x: 1, y: 'foo'}); -baz({x: 1, y: 'foo', z: 123}); +const baz1 = baz({x: 1}); +const baz2 = baz({x: 1, z: 123}); +const baz3 = baz({x: 1, y: 'foo'}); +const baz4 = baz({x: 1, y: 'foo', z: 123}); // ----------------------------------------------------------------------------------------- @@ -119,8 +113,6 @@ const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); type IsLiteralString = string extends T ? false : true; -type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } - interface ProvidedActor { src: string; logic: () => Promise; @@ -143,10 +135,6 @@ interface MachineConfig { }; } -type NoExtra = { - [K in keyof T]: K extends keyof MachineConfig ? T[K] : never -} - declare function createXMachine< const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, @@ -213,7 +201,6 @@ var checked = checkType()({ y: "y", z: "z", // undesirable property z is *not* allowed }); -checked; function doStuffWithStuff(s) { if (Math.random() > 0.5) { return s; @@ -222,7 +209,7 @@ function doStuffWithStuff(s) { return s; } } -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); +var stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); function doStuffWithStuffArr(arr) { if (Math.random() > 0.5) { return arr; @@ -231,18 +218,18 @@ function doStuffWithStuffArr(arr) { return arr; } } -doStuffWithStuffArr([ +var stuff2 = doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ]); function bar(props) { return foo(props); // no error because lack of excess property check by design } -foo({ x: 1, y: 'foo' }); -foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design -baz({ x: 1 }); -baz({ x: 1, z: 123 }); -baz({ x: 1, y: 'foo' }); -baz({ x: 1, y: 'foo', z: 123 }); +var foo1 = foo({ x: 1, y: 'foo' }); +var foo2 = foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design +var baz1 = baz({ x: 1 }); +var baz2 = baz({ x: 1, z: 123 }); +var baz3 = baz({ x: 1, y: 'foo' }); +var baz4 = baz({ x: 1, y: 'foo', z: 123 }); var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); var child = function () { return Promise.resolve("foo"); }; var config = createXMachine({ diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols index 12cb8664c8409..ba564a7c6f906 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols @@ -17,82 +17,72 @@ type StateConfig = { }; -type StateSchema = { ->StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) - - states?: Record; ->states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 20)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) - -}; - declare function createMachine< ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) TConfig extends StateConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) >StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 6, 39)) TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 6, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 2)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 8, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 8, 13)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) >StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 8, 13)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 6, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) const inferredParams1 = createMachine({ ->inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 5)) ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) +>inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 39)) +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) states: { ->states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 15, 15)) +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 11, 15)) a: { ->a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 16, 11)) +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 11)) entry: "bar", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 17, 8)) +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 13, 8)) }, }, extra: 12, ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 4)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 16, 4)) }); const inferredParams2 = createMachine({ ->inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 5)) ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) +>inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 39)) +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 39)) states: { ->states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 25, 15)) +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 21, 15)) a: { ->a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 26, 11)) +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 22, 11)) entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 27, 8)) +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 23, 8)) }, }, extra: 12, ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 30, 4)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 26, 4)) }); @@ -100,392 +90,377 @@ const inferredParams2 = createMachine({ // ----------------------------------------------------------------------------------------- const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) ->U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) ->value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) ->U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) ->U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) ->value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 5)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 19)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 41)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 51)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 28)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 51)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 41)) const checked = checkType<{x: number, y: string}>()({ ->checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) ->checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 27)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 37)) +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 5)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 27)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 37)) x: 1 as number, ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 53)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 53)) y: "y", ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 40, 17)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 36, 17)) z: "z", // undesirable property z is *not* allowed ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 41, 9)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 9)) }); -checked; ->checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) - // ----------------------------------------------------------------------------------------- interface Stuff { ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) field: number; ->field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 49, 17)) +>field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 43, 17)) anotherField: string; ->anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 50, 18)) +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 44, 18)) } function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 46, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 43)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) if(Math.random() > 0.5) { >Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) return s as T ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 43)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) } else { return s ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 43)) } } -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) ->field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 18)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 28)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 47)) +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>stuff1 : Symbol(stuff1, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 5)) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 46, 1)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 33)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 43)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 62)) function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 76)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 46)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) if(Math.random() > 0.5) { >Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) return arr as T[] ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 46)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) } else { return arr ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 46)) } } -doStuffWithStuffArr([ ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) +const stuff2 = doStuffWithStuffArr([ +>stuff2 : Symbol(stuff2, Decl(reverseMappedTypeIntersectionConstraint.ts, 66, 5)) +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 76)) { field: 1, anotherField: 'a', extra: 123 }, ->field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 5)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 15)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 34)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 67, 5)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 67, 15)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 67, 34)) ]) // ----------------------------------------------------------------------------------------- type XNumber = { x: number } ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 16)) - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 40)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 68, 2)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 16)) + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 68, 2)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 40)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 68, 2)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) function bar(props: {x: number, y: string}) { ->bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 93)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 21)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 31)) +>bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 90)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 13)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 21)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 31)) return foo(props); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 13)) } -foo({x: 1, y: 'foo'}); ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 5)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 10)) +const foo1 = foo({x: 1, y: 'foo'}); +>foo1 : Symbol(foo1, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 18)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 23)) -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 9)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 14)) +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo2 : Symbol(foo2, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 22)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 27)) // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 26)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 37)) - -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 50)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) - -baz({x: 1}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 96, 5)) - -baz({x: 1, z: 123}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 5)) ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 10)) - -baz({x: 1, y: 'foo'}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 5)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 10)) - -baz({x: 1, y: 'foo', z: 123}); ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 5)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 10)) ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 20)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 40)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 26)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 37)) + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 40)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 50)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 59)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 40)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 59)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) + +const baz1 = baz({x: 1}); +>baz1 : Symbol(baz1, Decl(reverseMappedTypeIntersectionConstraint.ts, 90, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 90, 18)) + +const baz2 = baz({x: 1, z: 123}); +>baz2 : Symbol(baz2, Decl(reverseMappedTypeIntersectionConstraint.ts, 91, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 91, 18)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 91, 23)) + +const baz3 = baz({x: 1, y: 'foo'}); +>baz3 : Symbol(baz3, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 18)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 23)) + +const baz4 = baz({x: 1, y: 'foo', z: 123}); +>baz4 : Symbol(baz4, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 18)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 23)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 33)) // ----------------------------------------------------------------------------------------- interface WithNestedProp { ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 43)) prop: string; ->prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 103, 26)) +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 26)) nested: { ->nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 15)) +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 15)) prop: string; ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 105, 11)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 11)) } } declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 58)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 102, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 43)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 58)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 43)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); ->wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 5)) ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 28)) ->nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 40)) ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 50)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 65)) +>wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 102, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 40)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 50)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 65)) // ----------------------------------------------------------------------------------------- type IsLiteralString = string extends T ? false : true; ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) - -type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } ->DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) ->Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) ->DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 79)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 21)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 21)) interface ProvidedActor { ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) src: string; ->src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 25)) +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 25)) logic: () => Promise; ->logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 14)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) } type DistributeActors = TActor extends { src: infer TSrc } ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 48)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 115, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 22)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 59)) ? { src: TSrc; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 126, 5)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 59)) } : never; interface MachineConfig { ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) types?: { ->types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 55)) +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 55)) actors?: TActor; ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 11)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 124, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) }; invoke: IsLiteralString extends true ->invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 4)) ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 126, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 79)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) ? DistributeActors ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 115, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) : { src: string; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 7)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 7)) }; } -type NoExtra = { ->NoExtra : Symbol(NoExtra, Decl(reverseMappedTypeIntersectionConstraint.ts, 140, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) - - [K in keyof T]: K extends keyof MachineConfig ? T[K] : never ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) -} - declare function createXMachine< ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 1)) const TConfig extends MachineConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 135, 46)) TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) ->types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 50)) ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 59)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 135, 46)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 136, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 136, 59)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 2)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 12)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 12)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) const child = () => Promise.resolve("foo"); ->child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 5)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) const config = createXMachine({ ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 5)) ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 141, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 1)) types: {} as { ->types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 31)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 141, 31)) actors: { ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 16)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 16)) src: "str"; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 13)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 13)) logic: typeof child; ->logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 17)) ->child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) +>logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 17)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 5)) }; }, invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 4)) +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 4)) src: "str", ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 160, 11)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 11)) }, extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 162, 4)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 4)) }); const config2 = createXMachine({ ->config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 5)) ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) +>config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 1)) invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 32)) +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) src: "whatever", ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 167, 11)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 11)) }, extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 169, 4)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 4)) }); diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types index 43b568dd83d87..03662df644eb1 100644 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types @@ -12,14 +12,6 @@ type StateConfig = { }; -type StateSchema = { ->StateSchema : { states?: Record | undefined; } - - states?: Record; ->states : Record | undefined - -}; - declare function createMachine< >createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] @@ -122,9 +114,6 @@ const checked = checkType<{x: number, y: string}>()({ }); -checked; ->checked : { x: number; y: "y"; } - // ----------------------------------------------------------------------------------------- interface Stuff { @@ -157,7 +146,8 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } } -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>stuff1 : { field: 1; anotherField: "a"; } >doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; } >doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T >{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } @@ -190,7 +180,8 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } } -doStuffWithStuffArr([ +const stuff2 = doStuffWithStuffArr([ +>stuff2 : { field: 1; anotherField: "a"; }[] >doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; }[] >doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] >[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] @@ -212,34 +203,36 @@ type XNumber = { x: number } >XNumber : { x: number; } >x : number -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T >props : { [K in keyof T & "x"]: T[K]; } function bar(props: {x: number, y: string}) { ->bar : (props: { x: number; y: string;}) => void +>bar : (props: { x: number; y: string;}) => { x: number; } >props : { x: number; y: string; } >x : number >y : string return foo(props); // no error because lack of excess property check by design ->foo(props) : void ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +>foo(props) : { x: number; } +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T >props : { x: number; y: string; } } -foo({x: 1, y: 'foo'}); ->foo({x: 1, y: 'foo'}) : void ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +const foo1 = foo({x: 1, y: 'foo'}); +>foo1 : { x: 1; } +>foo({x: 1, y: 'foo'}) : { x: 1; } +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T >{x: 1, y: 'foo'} : { x: 1; y: string; } >x : 1 >1 : 1 >y : string >'foo' : "foo" -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo({...{x: 1, y: 'foo'}}) : void ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => void +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo2 : { x: 1; } +>foo({...{x: 1, y: 'foo'}}) : { x: 1; } +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T >{...{x: 1, y: 'foo'}} : { x: 1; y: string; } >{x: 1, y: 'foo'} : { x: 1; y: string; } >x : 1 @@ -254,38 +247,42 @@ type NoErrWithOptProps = { x: number, y?: string } >x : number >y : string | undefined -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T >props : { [K in keyof T & keyof NoErrWithOptProps]: T[K]; } -baz({x: 1}); ->baz({x: 1}) : void ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +const baz1 = baz({x: 1}); +>baz1 : { x: 1; } +>baz({x: 1}) : { x: 1; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T >{x: 1} : { x: 1; } >x : 1 >1 : 1 -baz({x: 1, z: 123}); ->baz({x: 1, z: 123}) : void ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +const baz2 = baz({x: 1, z: 123}); +>baz2 : { x: 1; } +>baz({x: 1, z: 123}) : { x: 1; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T >{x: 1, z: 123} : { x: 1; z: number; } >x : 1 >1 : 1 >z : number >123 : 123 -baz({x: 1, y: 'foo'}); ->baz({x: 1, y: 'foo'}) : void ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +const baz3 = baz({x: 1, y: 'foo'}); +>baz3 : { x: 1; y: "foo"; } +>baz({x: 1, y: 'foo'}) : { x: 1; y: "foo"; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T >{x: 1, y: 'foo'} : { x: 1; y: "foo"; } >x : 1 >1 : 1 >y : "foo" >'foo' : "foo" -baz({x: 1, y: 'foo', z: 123}); ->baz({x: 1, y: 'foo', z: 123}) : void ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void +const baz4 = baz({x: 1, y: 'foo', z: 123}); +>baz4 : { x: 1; y: "foo"; } +>baz({x: 1, y: 'foo', z: 123}) : { x: 1; y: "foo"; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T >{x: 1, y: 'foo', z: 123} : { x: 1; y: "foo"; z: number; } >x : 1 >1 : 1 @@ -333,9 +330,6 @@ type IsLiteralString = string extends T ? false : true; >false : false >true : true -type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } ->DeepWritable : DeepWritable - interface ProvidedActor { src: string; >src : string @@ -374,12 +368,6 @@ interface MachineConfig { }; } -type NoExtra = { ->NoExtra : NoExtra - - [K in keyof T]: K extends keyof MachineConfig ? T[K] : never -} - declare function createXMachine< >createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig @@ -392,12 +380,12 @@ declare function createXMachine< >config : { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; } const child = () => Promise.resolve("foo"); ->child : () => any ->() => Promise.resolve("foo") : () => any ->Promise.resolve("foo") : any ->Promise.resolve : any ->Promise : any ->resolve : any +>child : () => Promise +>() => Promise.resolve("foo") : () => Promise +>Promise.resolve("foo") : Promise +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } +>Promise : PromiseConstructor +>resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } >"foo" : "foo" const config = createXMachine({ @@ -418,8 +406,8 @@ const config = createXMachine({ >src : "str" logic: typeof child; ->logic : () => any ->child : () => any +>logic : () => Promise +>child : () => Promise }; }, diff --git a/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts b/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType1.ts similarity index 100% rename from tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType.ts rename to tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType1.ts diff --git a/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType2.ts b/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType2.ts new file mode 100644 index 0000000000000..737050c533a26 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeInferFromFilteringNameType2.ts @@ -0,0 +1,150 @@ +// @strict: true +// @lib: esnext +// @noEmit: true + +type StateConfig = { + entry?: TAction; + states?: Record>; +}; +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string + ? TConfig["entry"] + : string, +>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K] }): [ + TAction, + TConfig, +]; +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); + +const checkType = + () => + (value: { [K in keyof U as K & keyof T]: U[K] }) => + value; +const checked = checkType<{ x: number; y: string }>()({ + x: 1 as number, + y: "y", + z: "z", // undesirable property z is *not* allowed +}); + +interface Stuff { + field: number; + anotherField: string; +} +function doStuffWithStuff(s: { + [K in keyof T as K & keyof Stuff]: T[K]; +}): T { + if (Math.random() > 0.5) { + return s as T; + } else { + return s; + } +} +const stuff1 = doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }); +function doStuffWithStuffArr( + arr: { [K in keyof T as K & keyof Stuff]: T[K] }[], +): T[] { + if (Math.random() > 0.5) { + return arr as T[]; + } else { + return arr; + } +} +const stuff2 = doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]); + +type XNumber = { x: number }; +declare function foo(props: { + [K in keyof T as K & keyof XNumber]: T[K]; +}): T; +function bar(props: { x: number; y: string }) { + return foo(props); // no error because lack of excess property check by design +} +const foo1 = foo({ x: 1, y: "foo" }); +const foo2 = foo({ ...{ x: 1, y: "foo" } }); // no error because lack of excess property check by design + +type NoErrWithOptProps = { x: number; y?: string }; +declare function baz(props: { + [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; +}): T; +const baz1 = baz({ x: 1 }); +const baz2 = baz({ x: 1, z: 123 }); +const baz3 = baz({ x: 1, y: "foo" }); +const baz4 = baz({ x: 1, y: "foo", z: 123 }); + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + }; +} +declare function withNestedProp(props: { + [K in keyof T as K & keyof WithNestedProp]: T[K]; +}): T; +const wnp = withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }); + +type IsLiteralString = string extends T ? false : true; +interface ProvidedActor { + src: string; + logic: () => Promise; +} +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} +declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { + types: { actors: ProvidedActor }; + } + ? TConfig["types"]["actors"] + : ProvidedActor, +>(config: { + [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; +}): TConfig; +const child = () => Promise.resolve("foo"); +const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10, +}); +const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10, +}); diff --git a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts index e565549791177..c86372d68ece2 100644 --- a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts +++ b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts @@ -1,14 +1,11 @@ // @strict: true +// @lib: esnext type StateConfig = { entry?: TAction states?: Record>; }; -type StateSchema = { - states?: Record; -}; - declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, @@ -45,8 +42,6 @@ const checked = checkType<{x: number, y: string}>()({ z: "z", // undesirable property z is *not* allowed }); -checked; - // ----------------------------------------------------------------------------------------- interface Stuff { @@ -62,7 +57,7 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } } -doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { if(Math.random() > 0.5) { @@ -72,7 +67,7 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } } -doStuffWithStuffArr([ +const stuff2 = doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ]) @@ -80,26 +75,26 @@ doStuffWithStuffArr([ type XNumber = { x: number } -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; function bar(props: {x: number, y: string}) { return foo(props); // no error because lack of excess property check by design } -foo({x: 1, y: 'foo'}); +const foo1 = foo({x: 1, y: 'foo'}); -foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; -baz({x: 1}); -baz({x: 1, z: 123}); -baz({x: 1, y: 'foo'}); -baz({x: 1, y: 'foo', z: 123}); +const baz1 = baz({x: 1}); +const baz2 = baz({x: 1, z: 123}); +const baz3 = baz({x: 1, y: 'foo'}); +const baz4 = baz({x: 1, y: 'foo', z: 123}); // ----------------------------------------------------------------------------------------- @@ -118,8 +113,6 @@ const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); type IsLiteralString = string extends T ? false : true; -type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } - interface ProvidedActor { src: string; logic: () => Promise; @@ -142,10 +135,6 @@ interface MachineConfig { }; } -type NoExtra = { - [K in keyof T]: K extends keyof MachineConfig ? T[K] : never -} - declare function createXMachine< const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, From 3a4490478e0a20d0d7e9adbf7575aaf40870b112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 30 Dec 2023 20:00:06 +0100 Subject: [PATCH 03/13] Limit inferred keys based on `nameType` too --- src/compiler/checker.ts | 28 ++++-- ...TypeInferFromFilteringNameType1.errors.txt | 6 +- ...appedTypeInferFromFilteringNameType1.types | 4 +- ...appedTypeInferFromFilteringNameType2.types | 44 ++++----- ...reverseMappedTypeLimitedConstraint.symbols | 55 ----------- ...onstraintWithFilteringNameType1.errors.txt | 34 +++++++ ...edConstraintWithFilteringNameType1.symbols | 95 ++++++++++++++++++ ...itedConstraintWithFilteringNameType1.types | 99 +++++++++++++++++++ ...tedConstraintWithIntersection1.errors.txt} | 9 +- ...TypeLimitedConstraintWithIntersection1.js} | 10 +- ...LimitedConstraintWithIntersection1.symbols | 56 +++++++++++ ...eLimitedConstraintWithIntersection1.types} | 5 +- ...LimitedConstraintWithFilteringNameType1.ts | 27 +++++ ...TypeLimitedConstraintWithIntersection1.ts} | 4 +- 14 files changed, 374 insertions(+), 102 deletions(-) delete mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types rename tests/baselines/reference/{reverseMappedTypeLimitedConstraint.errors.txt => reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt} (61%) rename tests/baselines/reference/{reverseMappedTypeLimitedConstraint.js => reverseMappedTypeLimitedConstraintWithIntersection1.js} (74%) create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols rename tests/baselines/reference/{reverseMappedTypeLimitedConstraint.types => reverseMappedTypeLimitedConstraintWithIntersection1.types} (90%) create mode 100644 tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts rename tests/cases/compiler/{reverseMappedTypeLimitedConstraint.ts => reverseMappedTypeLimitedConstraintWithIntersection1.ts} (95%) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 006aad2344d33..18a7f93c3e352 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13653,15 +13653,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // e.g. { [K in keyof U & ("a" | "b") ] } -> "a" | "b" function getLimitedConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); - if (!(constraint.flags & TypeFlags.Union || constraint.flags & TypeFlags.Intersection)) { + if (constraint === type.constraintType) { return; } - const origin = (constraint.flags & TypeFlags.Union) ? (constraint as UnionType).origin : (constraint as IntersectionType); - if (!origin || !(origin.flags & TypeFlags.Intersection)) { + const recordSymbol = getGlobalRecordSymbol(); + if (!recordSymbol) { return; } - const limitedConstraint = getIntersectionType((origin as IntersectionType).types.filter(t => t !== type.constraintType)); - return limitedConstraint !== neverType ? limitedConstraint : undefined; + const keyofConstraintRecord = getTypeAliasInstantiation(recordSymbol, [keyofConstraintType, unknownType]); + const mapper = appendTypeMapping(type.mappedType.mapper, type.constraintType.type, keyofConstraintRecord); + return instantiateType(constraint, mapper); } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { @@ -13672,15 +13673,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; const members = createSymbolTable(); const limitedConstraint = getLimitedConstraint(type); + const nameType = getNameTypeFromMappedType(type.mappedType); + for (const prop of getPropertiesOfType(type.source)) { // In case of a reverse mapped type with an intersection constraint, if we were able to // extract the filtering type literals we skip those properties that are not assignable to them, // because the extra properties wouldn't get through the application of the mapped type anyway - if (limitedConstraint) { + if (limitedConstraint || nameType) { const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); - if (!isTypeAssignableTo(propertyNameType, limitedConstraint)) { + if (limitedConstraint && !isTypeAssignableTo(propertyNameType, limitedConstraint)) { continue; } + if (nameType) { + const nameMapper = appendTypeMapping(type.mappedType.mapper, getTypeParameterFromMappedType(type.mappedType), propertyNameType) + const instantiatedNameType = instantiateType(nameType, nameMapper); + if (instantiatedNameType.flags & TypeFlags.Never) { + continue; + } + } } const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol; @@ -25692,9 +25702,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean { - if ((constraintType.flags & TypeFlags.Union) || (constraintType.flags & TypeFlags.Intersection)) { + if (constraintType.flags & TypeFlags.UnionOrIntersection) { let result = false; - for (const type of (constraintType as (UnionType | IntersectionType)).types) { + for (const type of (constraintType as (UnionOrIntersectionType)).types) { result = inferToMappedType(source, target, type) || result; } return result; diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt index aa0f075728126..9023a1fd6e2d7 100644 --- a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.errors.txt @@ -1,4 +1,4 @@ -reverseMappedTypeInferFromFilteringNameType1.ts(34,7): error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. +reverseMappedTypeInferFromFilteringNameType1.ts(34,7): error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; }>'. ==== reverseMappedTypeInferFromFilteringNameType1.ts (1 errors) ==== @@ -37,8 +37,8 @@ reverseMappedTypeInferFromFilteringNameType1.ts(34,7): error TS2353: Object lite last: true, doesntExist: true // error ~~~~~~~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; doesntExist: boolean; }>'. -!!! related TS6500 reverseMappedTypeInferFromFilteringNameType1.ts:14:7: The expected type comes from property 'needs' which is declared here on type '{ needs: AllowedNeeds<{ last: boolean; doesntExist: boolean; }>; compute: (x: Pick) => any; }' +!!! error TS2353: Object literal may only specify known properties, and 'doesntExist' does not exist in type 'AllowedNeeds<{ last: boolean; }>'. +!!! related TS6500 reverseMappedTypeInferFromFilteringNameType1.ts:14:7: The expected type comes from property 'needs' which is declared here on type '{ needs: AllowedNeeds<{ last: boolean; }>; compute: (x: Pick) => any; }' }, compute: (user) => {}, }, diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types index 6f512c87462e5..1cc5004319d1e 100644 --- a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType1.types @@ -77,8 +77,8 @@ const inferred1 = extend({ }); const inferred2 = extend({ ->inferred2 : { fullName: { last: boolean; doesntExist: boolean; }; } ->extend({ fullName: { needs: { last: true, doesntExist: true // error }, compute: (user) => {}, },}) : { fullName: { last: boolean; doesntExist: boolean; }; } +>inferred2 : { fullName: { last: boolean; }; } +>extend({ fullName: { needs: { last: true, doesntExist: true // error }, compute: (user) => {}, },}) : { fullName: { last: boolean; }; } >extend : (input: { [K in keyof T]: { needs: AllowedNeeds; compute: (x: Pick) => any; }; }) => T >{ fullName: { needs: { last: true, doesntExist: true // error }, compute: (user) => {}, },} : { fullName: { needs: { last: true; doesntExist: boolean; }; compute: (user: Pick) => void; }; } diff --git a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types index c1834b72ce0bb..6cd5ffdd64f9e 100644 --- a/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types +++ b/tests/baselines/reference/reverseMappedTypeInferFromFilteringNameType2.types @@ -54,8 +54,8 @@ const inferredParams1 = createMachine({ }); const inferredParams2 = createMachine({ ->inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] ->createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; }] +>inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] >createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig as K & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] >{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } @@ -151,8 +151,8 @@ function doStuffWithStuff(s: { } } const stuff1 = doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }); ->stuff1 : { field: 1; anotherField: "a"; extra: number; } ->doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }) : { field: 1; anotherField: "a"; extra: number; } +>stuff1 : { field: 1; anotherField: "a"; } +>doStuffWithStuff({ field: 1, anotherField: "a", extra: 123 }) : { field: 1; anotherField: "a"; } >doStuffWithStuff : (s: { [K in keyof T as K & keyof Stuff]: T[K]; }) => T >{ field: 1, anotherField: "a", extra: 123 } : { field: 1; anotherField: "a"; extra: number; } >field : 1 @@ -187,8 +187,8 @@ function doStuffWithStuffArr( } } const stuff2 = doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]); ->stuff2 : { field: 1; anotherField: "a"; extra: number; }[] ->doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]) : { field: 1; anotherField: "a"; extra: number; }[] +>stuff2 : { field: 1; anotherField: "a"; }[] +>doStuffWithStuffArr([{ field: 1, anotherField: "a", extra: 123 }]) : { field: 1; anotherField: "a"; }[] >doStuffWithStuffArr : (arr: { [K in keyof T as K & keyof Stuff]: T[K]; }[]) => T[] >[{ field: 1, anotherField: "a", extra: 123 }] : { field: 1; anotherField: "a"; extra: number; }[] >{ field: 1, anotherField: "a", extra: 123 } : { field: 1; anotherField: "a"; extra: number; } @@ -210,19 +210,19 @@ declare function foo(props: { [K in keyof T as K & keyof XNumber]: T[K]; }): T; function bar(props: { x: number; y: string }) { ->bar : (props: { x: number; y: string;}) => { x: number; y: string; } +>bar : (props: { x: number; y: string;}) => { x: number; } >props : { x: number; y: string; } >x : number >y : string return foo(props); // no error because lack of excess property check by design ->foo(props) : { x: number; y: string; } +>foo(props) : { x: number; } >foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T >props : { x: number; y: string; } } const foo1 = foo({ x: 1, y: "foo" }); ->foo1 : { x: 1; y: string; } ->foo({ x: 1, y: "foo" }) : { x: 1; y: string; } +>foo1 : { x: 1; } +>foo({ x: 1, y: "foo" }) : { x: 1; } >foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T >{ x: 1, y: "foo" } : { x: 1; y: string; } >x : 1 @@ -231,8 +231,8 @@ const foo1 = foo({ x: 1, y: "foo" }); >"foo" : "foo" const foo2 = foo({ ...{ x: 1, y: "foo" } }); // no error because lack of excess property check by design ->foo2 : { x: 1; y: string; } ->foo({ ...{ x: 1, y: "foo" } }) : { x: 1; y: string; } +>foo2 : { x: 1; } +>foo({ ...{ x: 1, y: "foo" } }) : { x: 1; } >foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T >{ ...{ x: 1, y: "foo" } } : { x: 1; y: string; } >{ x: 1, y: "foo" } : { x: 1; y: string; } @@ -261,8 +261,8 @@ const baz1 = baz({ x: 1 }); >1 : 1 const baz2 = baz({ x: 1, z: 123 }); ->baz2 : { x: 1; z: number; } ->baz({ x: 1, z: 123 }) : { x: 1; z: number; } +>baz2 : { x: 1; } +>baz({ x: 1, z: 123 }) : { x: 1; } >baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T >{ x: 1, z: 123 } : { x: 1; z: number; } >x : 1 @@ -281,8 +281,8 @@ const baz3 = baz({ x: 1, y: "foo" }); >"foo" : "foo" const baz4 = baz({ x: 1, y: "foo", z: 123 }); ->baz4 : { x: 1; y: "foo"; z: number; } ->baz({ x: 1, y: "foo", z: 123 }) : { x: 1; y: "foo"; z: number; } +>baz4 : { x: 1; y: "foo"; } +>baz({ x: 1, y: "foo", z: 123 }) : { x: 1; y: "foo"; } >baz : (props: { [K in keyof T as K & keyof NoErrWithOptProps]: T[K]; }) => T >{ x: 1, y: "foo", z: 123 } : { x: 1; y: "foo"; z: number; } >x : 1 @@ -311,8 +311,8 @@ declare function withNestedProp(props: { [K in keyof T as K & keyof WithNestedProp]: T[K]; }): T; const wnp = withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }); ->wnp : { prop: "foo"; nested: { prop: string; }; extra: number; } ->withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; extra: number; } +>wnp : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp({ prop: "foo", nested: { prop: "bar" }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; } >withNestedProp : (props: { [K in keyof T as K & keyof WithNestedProp]: T[K]; }) => T >{ prop: "foo", nested: { prop: "bar" }, extra: 10 } : { prop: "foo"; nested: { prop: string; }; extra: number; } >prop : "foo" @@ -390,8 +390,8 @@ const child = () => Promise.resolve("foo"); >"foo" : "foo" const config = createXMachine({ ->config : { readonly types: { actors: { src: "str"; logic: typeof child;}; }; readonly invoke: { readonly src: "str"; }; readonly extra: 10; } ->createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10,}) : { readonly types: { actors: { src: "str"; logic: typeof child;}; }; readonly invoke: { readonly src: "str"; }; readonly extra: 10; } +>config : { readonly types: { actors: { src: "str"; logic: typeof child;}; }; readonly invoke: { readonly src: "str"; }; } +>createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10,}) : { readonly types: { actors: { src: "str"; logic: typeof child;}; }; readonly invoke: { readonly src: "str"; }; } >createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; }) => TConfig >{ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10,} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } @@ -427,8 +427,8 @@ const config = createXMachine({ }); const config2 = createXMachine({ ->config2 : { readonly invoke: { readonly src: "whatever"; }; readonly extra: 10; } ->createXMachine({ invoke: { src: "whatever", }, extra: 10,}) : { readonly invoke: { readonly src: "whatever"; }; readonly extra: 10; } +>config2 : { readonly invoke: { readonly src: "whatever"; }; } +>createXMachine({ invoke: { src: "whatever", }, extra: 10,}) : { readonly invoke: { readonly src: "whatever"; }; } >createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof TConfig as K & keyof MachineConfig]: TConfig[K]; }) => TConfig >{ invoke: { src: "whatever", }, extra: 10,} : { invoke: { src: "whatever"; }; extra: number; } diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols deleted file mode 100644 index 5c81507278445..0000000000000 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols +++ /dev/null @@ -1,55 +0,0 @@ -//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// - -=== reverseMappedTypeLimitedConstraint.ts === -type XNumber_ = { x: number } ->XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 17)) - -declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; ->foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) ->XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 42)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) ->XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) - -foo_({x: 1, y: 'foo'}); ->foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 6)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 11)) - -// ----------------------------------------------------------------------------------------- - -const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) ->value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) ->value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) - -const checked_ = checkType_<{x: number, y: string}>()({ ->checked_ : Symbol(checked_, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 5)) ->checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 29)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 39)) - - x: 1 as number, ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 55)) - - y: "y", ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 11, 17)) - - z: "z", ->z : Symbol(z, Decl(reverseMappedTypeLimitedConstraint.ts, 12, 9)) - -}); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt new file mode 100644 index 0000000000000..c1c2943c07df6 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt @@ -0,0 +1,34 @@ +reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts(5,26): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts(17,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + + +==== reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts (2 errors) ==== + type XNumber = { x: number }; + declare function foo(props: { + [K in keyof T as K & keyof XNumber]: T[K]; + }): T; + const foo1 = foo({ x: 1, y: "foo" }); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + const objFoo = { x: 1, y: "foo" }; + const foo2 = foo(objFoo); + + const checkType = + () => + (value: { [K in keyof U & keyof T]: U[K] }) => + value; + + const checked1 = checkType<{ x: number; y: string }>()({ + x: 1 as number, + y: "y", + z: "z", + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); + const objChecked = { + x: 1, + y: "y", + z: "z", + }; + const checked2 = checkType<{ x: number; y: string }>()(objChecked); + \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols new file mode 100644 index 0000000000000..d3d9e46d13035 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols @@ -0,0 +1,95 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts] //// + +=== reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts === +type XNumber = { x: number }; +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 0)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 16)) + +declare function foo(props: { +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 1, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 0)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 1, 40)) + + [K in keyof T as K & keyof XNumber]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 2, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 1, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 2, 3)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 1, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 2, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 1, 21)) + +const foo1 = foo({ x: 1, y: "foo" }); +>foo1 : Symbol(foo1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 4, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 29)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 4, 18)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 4, 24)) + +const objFoo = { x: 1, y: "foo" }; +>objFoo : Symbol(objFoo, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 5, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 5, 16)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 5, 22)) + +const foo2 = foo(objFoo); +>foo2 : Symbol(foo2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 6, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 0, 29)) +>objFoo : Symbol(objFoo, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 5, 5)) + +const checkType = +>checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 8, 5)) + + () => +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 9, 3)) + + (value: { [K in keyof U & keyof T]: U[K] }) => +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 9, 3)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 16)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 26)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 9, 3)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 3)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 26)) + + value; +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 10, 16)) + +const checked1 = checkType<{ x: number; y: string }>()({ +>checked1 : Symbol(checked1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 13, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 8, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 13, 28)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 13, 39)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 13, 56)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 14, 17)) + + z: "z", +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 15, 9)) + +}); +const objChecked = { +>objChecked : Symbol(objChecked, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 18, 5)) + + x: 1, +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 18, 20)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 19, 7)) + + z: "z", +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 20, 9)) + +}; +const checked2 = checkType<{ x: number; y: string }>()(objChecked); +>checked2 : Symbol(checked2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 8, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 28)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 39)) +>objChecked : Symbol(objChecked, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 18, 5)) + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types new file mode 100644 index 0000000000000..fa21d7465d397 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types @@ -0,0 +1,99 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts] //// + +=== reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts === +type XNumber = { x: number }; +>XNumber : { x: number; } +>x : number + +declare function foo(props: { +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>props : { [K in keyof T as K & "x"]: T[K]; } + + [K in keyof T as K & keyof XNumber]: T[K]; +}): T; +const foo1 = foo({ x: 1, y: "foo" }); +>foo1 : { x: 1; } +>foo({ x: 1, y: "foo" }) : { x: 1; } +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>{ x: 1, y: "foo" } : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>"foo" : "foo" + +const objFoo = { x: 1, y: "foo" }; +>objFoo : { x: number; y: string; } +>{ x: 1, y: "foo" } : { x: number; y: string; } +>x : number +>1 : 1 +>y : string +>"foo" : "foo" + +const foo2 = foo(objFoo); +>foo2 : { x: number; } +>foo(objFoo) : { x: number; } +>foo : (props: { [K in keyof T as K & "x"]: T[K]; }) => T +>objFoo : { x: number; y: string; } + +const checkType = +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } + + () => +>() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } + + (value: { [K in keyof U & keyof T]: U[K] }) => +>(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } + + value; +>value : { [K in keyof U & keyof T]: U[K]; } + +const checked1 = checkType<{ x: number; y: string }>()({ +>checked1 : { x: number; y: "y"; } +>checkType<{ x: number; y: string }>()({ x: 1 as number, y: "y", z: "z",}) : { x: number; y: "y"; } +>checkType<{ x: number; y: string }>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z",} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", +>z : string +>"z" : "z" + +}); +const objChecked = { +>objChecked : { x: number; y: string; z: string; } +>{ x: 1, y: "y", z: "z",} : { x: number; y: string; z: string; } + + x: 1, +>x : number +>1 : 1 + + y: "y", +>y : string +>"y" : "y" + + z: "z", +>z : string +>"z" : "z" + +}; +const checked2 = checkType<{ x: number; y: string }>()(objChecked); +>checked2 : { x: number; y: string; } +>checkType<{ x: number; y: string }>()(objChecked) : { x: number; y: string; } +>checkType<{ x: number; y: string }>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>objChecked : { x: number; y: string; z: string; } + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt similarity index 61% rename from tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt rename to tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt index dc6dc8fa3a331..654a3e5c75869 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt @@ -1,8 +1,8 @@ -reverseMappedTypeLimitedConstraint.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseMappedTypeLimitedConstraint.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -==== reverseMappedTypeLimitedConstraint.ts (2 errors) ==== +==== reverseMappedTypeLimitedConstraintWithIntersection1.ts (2 errors) ==== type XNumber_ = { x: number } declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; @@ -21,4 +21,5 @@ reverseMappedTypeLimitedConstraint.ts(14,3): error TS2353: Object literal may on z: "z", ~ !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. - }); \ No newline at end of file + }); + \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js similarity index 74% rename from tests/baselines/reference/reverseMappedTypeLimitedConstraint.js rename to tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js index 0be7aa8d6a423..ad35f4aace2c9 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// -//// [reverseMappedTypeLimitedConstraint.ts] +//// [reverseMappedTypeLimitedConstraintWithIntersection1.ts] type XNumber_ = { x: number } declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; @@ -15,9 +15,11 @@ const checked_ = checkType_<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z", -}); +}); + -//// [reverseMappedTypeLimitedConstraint.js] +//// [reverseMappedTypeLimitedConstraintWithIntersection1.js] +"use strict"; foo_({ x: 1, y: 'foo' }); // ----------------------------------------------------------------------------------------- var checkType_ = function () { return function (value) { return value; }; }; diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols new file mode 100644 index 0000000000000..a488e609f13b8 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// + +=== reverseMappedTypeLimitedConstraintWithIntersection1.ts === +type XNumber_ = { x: number } +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) + +foo_({x: 1, y: 'foo'}); +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 29)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 4, 6)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 4, 11)) + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 5)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 20)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 52)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 29)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 52)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 42)) + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : Symbol(checked_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 5)) +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 29)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 39)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 55)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 11, 17)) + + z: "z", +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 12, 9)) + +}); + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types similarity index 90% rename from tests/baselines/reference/reverseMappedTypeLimitedConstraint.types rename to tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types index 821d7685fcccd..52b112a09a0d4 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// -=== reverseMappedTypeLimitedConstraint.ts === +=== reverseMappedTypeLimitedConstraintWithIntersection1.ts === type XNumber_ = { x: number } >XNumber_ : { x: number; } >x : number @@ -50,3 +50,4 @@ const checked_ = checkType_<{x: number, y: string}>()({ >"z" : "z" }); + diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts new file mode 100644 index 0000000000000..37f3b56dbcad3 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts @@ -0,0 +1,27 @@ +// @strict: true +// @noEmit: true + +type XNumber = { x: number }; +declare function foo(props: { + [K in keyof T as K & keyof XNumber]: T[K]; +}): T; +const foo1 = foo({ x: 1, y: "foo" }); +const objFoo = { x: 1, y: "foo" }; +const foo2 = foo(objFoo); + +const checkType = + () => + (value: { [K in keyof U & keyof T]: U[K] }) => + value; + +const checked1 = checkType<{ x: number; y: string }>()({ + x: 1 as number, + y: "y", + z: "z", +}); +const objChecked = { + x: 1, + y: "y", + z: "z", +}; +const checked2 = checkType<{ x: number; y: string }>()(objChecked); diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts similarity index 95% rename from tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts rename to tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts index 7618ae65046a9..4db2da39172db 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts @@ -1,3 +1,5 @@ +// @strict: true + type XNumber_ = { x: number } declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; @@ -12,4 +14,4 @@ const checked_ = checkType_<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z", -}); \ No newline at end of file +}); From 9dfeab26a7b4eb44f9e9b5d869a8c48f72d13f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 30 Dec 2023 20:02:38 +0100 Subject: [PATCH 04/13] fix format --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0e83fd3acbf8d..2866856a59f79 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13705,7 +13705,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { continue; } if (nameType) { - const nameMapper = appendTypeMapping(type.mappedType.mapper, getTypeParameterFromMappedType(type.mappedType), propertyNameType) + const nameMapper = appendTypeMapping(type.mappedType.mapper, getTypeParameterFromMappedType(type.mappedType), propertyNameType); const instantiatedNameType = instantiateType(nameType, nameMapper); if (instantiatedNameType.flags & TypeFlags.Never) { continue; From 602d628f5a13707b2a3241ca7bc3988e41c72ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 00:56:57 +0100 Subject: [PATCH 05/13] grab the constraint of limited constraint --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2866856a59f79..cd94a0d696057 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13682,7 +13682,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const keyofConstraintRecord = getTypeAliasInstantiation(recordSymbol, [keyofConstraintType, unknownType]); const mapper = appendTypeMapping(type.mappedType.mapper, type.constraintType.type, keyofConstraintRecord); - return instantiateType(constraint, mapper); + return getBaseConstraintOfType(instantiateType(constraint, mapper)); } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { @@ -25761,7 +25761,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean { if (constraintType.flags & TypeFlags.UnionOrIntersection) { let result = false; - for (const type of (constraintType as (UnionOrIntersectionType)).types) { + for (const type of (constraintType as UnionOrIntersectionType).types) { result = inferToMappedType(source, target, type) || result; } return result; From d1f90067e1871c6ef7a1798bab008a1d345381e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 10:32:06 +0100 Subject: [PATCH 06/13] fix the get base constraint call --- src/compiler/checker.ts | 2 +- ...appedTypeIntersectionConstraint.errors.txt | 210 -------- ...reverseMappedTypeIntersectionConstraint.js | 247 --------- ...seMappedTypeIntersectionConstraint.symbols | 466 ----------------- ...erseMappedTypeIntersectionConstraint.types | 449 ---------------- ...itedConstraintWithIntersection1.errors.txt | 207 +++++++- ...dTypeLimitedConstraintWithIntersection1.js | 237 ++++++++- ...LimitedConstraintWithIntersection1.symbols | 494 ++++++++++++++++-- ...peLimitedConstraintWithIntersection1.types | 442 +++++++++++++++- ...reverseMappedTypeIntersectionConstraint.ts | 163 ------ ...dTypeLimitedConstraintWithIntersection1.ts | 158 +++++- 11 files changed, 1447 insertions(+), 1628 deletions(-) delete mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt delete mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js delete mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols delete mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types delete mode 100644 tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cd94a0d696057..9c1e22e052235 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13682,7 +13682,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const keyofConstraintRecord = getTypeAliasInstantiation(recordSymbol, [keyofConstraintType, unknownType]); const mapper = appendTypeMapping(type.mappedType.mapper, type.constraintType.type, keyofConstraintRecord); - return getBaseConstraintOfType(instantiateType(constraint, mapper)); + return getBaseConstraintOrType(instantiateType(constraint, mapper)); } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt deleted file mode 100644 index db13e745a1600..0000000000000 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt +++ /dev/null @@ -1,210 +0,0 @@ -reverseMappedTypeIntersectionConstraint.ts(15,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. -reverseMappedTypeIntersectionConstraint.ts(28,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. -reverseMappedTypeIntersectionConstraint.ts(39,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -reverseMappedTypeIntersectionConstraint.ts(53,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. - '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeIntersectionConstraint.ts(57,64): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeIntersectionConstraint.ts(63,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. - Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. - '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeIntersectionConstraint.ts(68,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeIntersectionConstraint.ts(81,25): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseMappedTypeIntersectionConstraint.ts(92,25): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. -reverseMappedTypeIntersectionConstraint.ts(94,35): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. -reverseMappedTypeIntersectionConstraint.ts(107,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. -reverseMappedTypeIntersectionConstraint.ts(152,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. -reverseMappedTypeIntersectionConstraint.ts(159,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. - - -==== reverseMappedTypeIntersectionConstraint.ts (13 errors) ==== - type StateConfig = { - entry?: TAction - states?: Record>; - }; - - declare function createMachine< - TConfig extends StateConfig, - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, - >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; - - const inferredParams1 = createMachine({ - entry: "foo", - states: { - a: { - entry: "bar", - ~~~~~ -!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. -!!! related TS6500 reverseMappedTypeIntersectionConstraint.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' - }, - }, - extra: 12, - }); - - const inferredParams2 = createMachine({ - entry: "foo", - states: { - a: { - entry: "foo", - }, - }, - extra: 12, - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. - }); - - - // ----------------------------------------------------------------------------------------- - - const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; - - const checked = checkType<{x: number, y: string}>()({ - x: 1 as number, - y: "y", - z: "z", // undesirable property z is *not* allowed - ~ -!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. - }); - - // ----------------------------------------------------------------------------------------- - - interface Stuff { - field: number; - anotherField: string; - } - - function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { - if(Math.random() > 0.5) { - return s as T - } else { - return s - ~~~~~~ -!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. -!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. - } - } - - const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. - - function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { - if(Math.random() > 0.5) { - return arr as T[] - } else { - return arr - ~~~~~~ -!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. -!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. -!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. - } - } - - const stuff2 = doStuffWithStuffArr([ - { field: 1, anotherField: 'a', extra: 123 }, - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. - ]) - - // ----------------------------------------------------------------------------------------- - - type XNumber = { x: number } - - declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; - - function bar(props: {x: number, y: string}) { - return foo(props); // no error because lack of excess property check by design - } - - const foo1 = foo({x: 1, y: 'foo'}); - ~ -!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. - - const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design - - // ----------------------------------------------------------------------------------------- - - type NoErrWithOptProps = { x: number, y?: string } - - declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; - - const baz1 = baz({x: 1}); - const baz2 = baz({x: 1, z: 123}); - ~ -!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. - const baz3 = baz({x: 1, y: 'foo'}); - const baz4 = baz({x: 1, y: 'foo', z: 123}); - ~ -!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. - - // ----------------------------------------------------------------------------------------- - - interface WithNestedProp { - prop: string; - nested: { - prop: string; - } - } - - declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; - - const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. - - // ----------------------------------------------------------------------------------------- - - type IsLiteralString = string extends T ? false : true; - - interface ProvidedActor { - src: string; - logic: () => Promise; - } - - type DistributeActors = TActor extends { src: infer TSrc } - ? { - src: TSrc; - } - : never; - - interface MachineConfig { - types?: { - actors?: TActor; - }; - invoke: IsLiteralString extends true - ? DistributeActors - : { - src: string; - }; - } - - declare function createXMachine< - const TConfig extends MachineConfig, - TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, - >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; - - const child = () => Promise.resolve("foo"); - - const config = createXMachine({ - types: {} as { - actors: { - src: "str"; - logic: typeof child; - }; - }, - invoke: { - src: "str", - }, - extra: 10 - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. - }); - - const config2 = createXMachine({ - invoke: { - src: "whatever", - }, - extra: 10 - ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. - }); - \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js deleted file mode 100644 index c97a340c71830..0000000000000 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js +++ /dev/null @@ -1,247 +0,0 @@ -//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// - -//// [reverseMappedTypeIntersectionConstraint.ts] -type StateConfig = { - entry?: TAction - states?: Record>; -}; - -declare function createMachine< - TConfig extends StateConfig, - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; - -const inferredParams1 = createMachine({ - entry: "foo", - states: { - a: { - entry: "bar", - }, - }, - extra: 12, -}); - -const inferredParams2 = createMachine({ - entry: "foo", - states: { - a: { - entry: "foo", - }, - }, - extra: 12, -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; - -const checked = checkType<{x: number, y: string}>()({ - x: 1 as number, - y: "y", - z: "z", // undesirable property z is *not* allowed -}); - -// ----------------------------------------------------------------------------------------- - -interface Stuff { - field: number; - anotherField: string; -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { - if(Math.random() > 0.5) { - return s as T - } else { - return s - } -} - -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { - if(Math.random() > 0.5) { - return arr as T[] - } else { - return arr - } -} - -const stuff2 = doStuffWithStuffArr([ - { field: 1, anotherField: 'a', extra: 123 }, -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; - -function bar(props: {x: number, y: string}) { - return foo(props); // no error because lack of excess property check by design -} - -const foo1 = foo({x: 1, y: 'foo'}); - -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design - -// ----------------------------------------------------------------------------------------- - -type NoErrWithOptProps = { x: number, y?: string } - -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; - -const baz1 = baz({x: 1}); -const baz2 = baz({x: 1, z: 123}); -const baz3 = baz({x: 1, y: 'foo'}); -const baz4 = baz({x: 1, y: 'foo', z: 123}); - -// ----------------------------------------------------------------------------------------- - -interface WithNestedProp { - prop: string; - nested: { - prop: string; - } -} - -declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; - -const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); - -// ----------------------------------------------------------------------------------------- - -type IsLiteralString = string extends T ? false : true; - -interface ProvidedActor { - src: string; - logic: () => Promise; -} - -type DistributeActors = TActor extends { src: infer TSrc } - ? { - src: TSrc; - } - : never; - -interface MachineConfig { - types?: { - actors?: TActor; - }; - invoke: IsLiteralString extends true - ? DistributeActors - : { - src: string; - }; -} - -declare function createXMachine< - const TConfig extends MachineConfig, - TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; - -const child = () => Promise.resolve("foo"); - -const config = createXMachine({ - types: {} as { - actors: { - src: "str"; - logic: typeof child; - }; - }, - invoke: { - src: "str", - }, - extra: 10 -}); - -const config2 = createXMachine({ - invoke: { - src: "whatever", - }, - extra: 10 -}); - - -//// [reverseMappedTypeIntersectionConstraint.js] -"use strict"; -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; -var inferredParams1 = createMachine({ - entry: "foo", - states: { - a: { - entry: "bar", - }, - }, - extra: 12, -}); -var inferredParams2 = createMachine({ - entry: "foo", - states: { - a: { - entry: "foo", - }, - }, - extra: 12, -}); -// ----------------------------------------------------------------------------------------- -var checkType = function () { return function (value) { return value; }; }; -var checked = checkType()({ - x: 1, - y: "y", - z: "z", // undesirable property z is *not* allowed -}); -function doStuffWithStuff(s) { - if (Math.random() > 0.5) { - return s; - } - else { - return s; - } -} -var stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); -function doStuffWithStuffArr(arr) { - if (Math.random() > 0.5) { - return arr; - } - else { - return arr; - } -} -var stuff2 = doStuffWithStuffArr([ - { field: 1, anotherField: 'a', extra: 123 }, -]); -function bar(props) { - return foo(props); // no error because lack of excess property check by design -} -var foo1 = foo({ x: 1, y: 'foo' }); -var foo2 = foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design -var baz1 = baz({ x: 1 }); -var baz2 = baz({ x: 1, z: 123 }); -var baz3 = baz({ x: 1, y: 'foo' }); -var baz4 = baz({ x: 1, y: 'foo', z: 123 }); -var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); -var child = function () { return Promise.resolve("foo"); }; -var config = createXMachine({ - types: {}, - invoke: { - src: "str", - }, - extra: 10 -}); -var config2 = createXMachine({ - invoke: { - src: "whatever", - }, - extra: 10 -}); diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols deleted file mode 100644 index ba564a7c6f906..0000000000000 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols +++ /dev/null @@ -1,466 +0,0 @@ -//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// - -=== reverseMappedTypeIntersectionConstraint.ts === -type StateConfig = { ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) - - entry?: TAction ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 44)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) - - states?: Record>; ->states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 1, 17)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) - -}; - -declare function createMachine< ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) - - TConfig extends StateConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 6, 39)) - - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 6, 39)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) - ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 8, 2)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 8, 13)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 8, 13)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 6, 39)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 31)) - -const inferredParams1 = createMachine({ ->inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 5)) ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) - - entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) - - states: { ->states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 11, 15)) - - a: { ->a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 11)) - - entry: "bar", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 13, 8)) - - }, - }, - extra: 12, ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 16, 4)) - -}); - -const inferredParams2 = createMachine({ ->inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 5)) ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) - - entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 39)) - - states: { ->states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 21, 15)) - - a: { ->a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 22, 11)) - - entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 23, 8)) - - }, - }, - extra: 12, ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 26, 4)) - -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 5)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 19)) ->U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 19)) ->value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 41)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 51)) ->U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 19)) ->U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 28)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 51)) ->value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 41)) - -const checked = checkType<{x: number, y: string}>()({ ->checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 5)) ->checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 33, 5)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 27)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 37)) - - x: 1 as number, ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 35, 53)) - - y: "y", ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 36, 17)) - - z: "z", // undesirable property z is *not* allowed ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 9)) - -}); - -// ----------------------------------------------------------------------------------------- - -interface Stuff { ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) - - field: number; ->field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 43, 17)) - - anotherField: string; ->anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 44, 18)) -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 46, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 43)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) - - if(Math.random() > 0.5) { ->Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - - return s as T ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 43)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 26)) - - } else { - return s ->s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 48, 43)) - } -} - -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->stuff1 : Symbol(stuff1, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 5)) ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 46, 1)) ->field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 33)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 43)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 62)) - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 76)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 46)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 54)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 3)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 54)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) - - if(Math.random() > 0.5) { ->Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - - return arr as T[] ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 46)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 29)) - - } else { - return arr ->arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 58, 46)) - } -} - -const stuff2 = doStuffWithStuffArr([ ->stuff2 : Symbol(stuff2, Decl(reverseMappedTypeIntersectionConstraint.ts, 66, 5)) ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 56, 76)) - - { field: 1, anotherField: 'a', extra: 123 }, ->field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 67, 5)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 67, 15)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 67, 34)) - -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 68, 2)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 16)) - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 68, 2)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 40)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 68, 2)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 49)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 21)) - -function bar(props: {x: number, y: string}) { ->bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 90)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 13)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 21)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 31)) - - return foo(props); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 76, 13)) -} - -const foo1 = foo({x: 1, y: 'foo'}); ->foo1 : Symbol(foo1, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 5)) ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 18)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 23)) - -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo2 : Symbol(foo2, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 5)) ->foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 72, 28)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 22)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 27)) - -// ----------------------------------------------------------------------------------------- - -type NoErrWithOptProps = { x: number, y?: string } ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 40)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 26)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 37)) - -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 40)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 50)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 59)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 40)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 59)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 21)) - -const baz1 = baz({x: 1}); ->baz1 : Symbol(baz1, Decl(reverseMappedTypeIntersectionConstraint.ts, 90, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 90, 18)) - -const baz2 = baz({x: 1, z: 123}); ->baz2 : Symbol(baz2, Decl(reverseMappedTypeIntersectionConstraint.ts, 91, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 91, 18)) ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 91, 23)) - -const baz3 = baz({x: 1, y: 'foo'}); ->baz3 : Symbol(baz3, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 18)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 23)) - -const baz4 = baz({x: 1, y: 'foo', z: 123}); ->baz4 : Symbol(baz4, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 18)) ->y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 23)) ->z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 33)) - -// ----------------------------------------------------------------------------------------- - -interface WithNestedProp { ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 43)) - - prop: string; ->prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 26)) - - nested: { ->nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 15)) - - prop: string; ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 11)) - } -} - -declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 102, 1)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 43)) ->props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 58)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 67)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 93, 43)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 67)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 32)) - -const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); ->wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 5)) ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 102, 1)) ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 28)) ->nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 40)) ->prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 50)) ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 65)) - -// ----------------------------------------------------------------------------------------- - -type IsLiteralString = string extends T ? false : true; ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 79)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 21)) ->T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 21)) - -interface ProvidedActor { ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) - - src: string; ->src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 25)) - - logic: () => Promise; ->logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 113, 14)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) -} - -type DistributeActors = TActor extends { src: infer TSrc } ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 115, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 22)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 22)) ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 48)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 59)) - - ? { - src: TSrc; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 5)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 117, 59)) - } - : never; - -interface MachineConfig { ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) - - types?: { ->types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 55)) - - actors?: TActor; ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 124, 11)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) - - }; - invoke: IsLiteralString extends true ->invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 126, 4)) ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 106, 79)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) - - ? DistributeActors ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 115, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 24)) - - : { - src: string; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 7)) - - }; -} - -declare function createXMachine< ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 1)) - - const TConfig extends MachineConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 135, 46)) - - TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 135, 46)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) ->types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 136, 50)) ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 136, 59)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 73)) - ->(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 2)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 12)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 10)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) ->K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 12)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 32)) - -const child = () => Promise.resolve("foo"); ->child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 5)) ->Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) ->resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) - -const config = createXMachine({ ->config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 141, 5)) ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 1)) - - types: {} as { ->types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 141, 31)) - - actors: { ->actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 16)) - - src: "str"; ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 13)) - - logic: typeof child; ->logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 17)) ->child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 139, 5)) - - }; - }, - invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 4)) - - src: "str", ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 11)) - - }, - extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 150, 4)) - -}); - -const config2 = createXMachine({ ->config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 5)) ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 1)) - - invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 32)) - - src: "whatever", ->src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 11)) - - }, - extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 157, 4)) - -}); - diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types deleted file mode 100644 index 03662df644eb1..0000000000000 --- a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types +++ /dev/null @@ -1,449 +0,0 @@ -//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// - -=== reverseMappedTypeIntersectionConstraint.ts === -type StateConfig = { ->StateConfig : StateConfig - - entry?: TAction ->entry : TAction | undefined - - states?: Record>; ->states : Record> | undefined - -}; - -declare function createMachine< ->createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] - - TConfig extends StateConfig, - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; ->config : { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; } - -const inferredParams1 = createMachine({ ->inferredParams1 : ["foo", StateConfig<"foo">] ->createMachine({ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,}) : ["foo", StateConfig<"foo">] ->createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] ->{ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "bar"; }; }; extra: number; } - - entry: "foo", ->entry : "foo" ->"foo" : "foo" - - states: { ->states : { a: { entry: "bar"; }; } ->{ a: { entry: "bar", }, } : { a: { entry: "bar"; }; } - - a: { ->a : { entry: "bar"; } ->{ entry: "bar", } : { entry: "bar"; } - - entry: "bar", ->entry : "bar" ->"bar" : "bar" - - }, - }, - extra: 12, ->extra : number ->12 : 12 - -}); - -const inferredParams2 = createMachine({ ->inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] ->createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] ->createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] ->{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } - - entry: "foo", ->entry : "foo" ->"foo" : "foo" - - states: { ->states : { a: { entry: "foo"; }; } ->{ a: { entry: "foo", }, } : { a: { entry: "foo"; }; } - - a: { ->a : { entry: "foo"; } ->{ entry: "foo", } : { entry: "foo"; } - - entry: "foo", ->entry : "foo" ->"foo" : "foo" - - }, - }, - extra: 12, ->extra : number ->12 : 12 - -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } ->() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } ->(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } ->value : { [K in keyof U & keyof T]: U[K]; } ->value : { [K in keyof U & keyof T]: U[K]; } - -const checked = checkType<{x: number, y: string}>()({ ->checked : { x: number; y: "y"; } ->checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed}) : { x: number; y: "y"; } ->checkType<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } ->checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } ->x : number ->y : string ->{ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed} : { x: number; y: "y"; z: string; } - - x: 1 as number, ->x : number ->1 as number : number ->1 : 1 - - y: "y", ->y : "y" ->"y" : "y" - - z: "z", // undesirable property z is *not* allowed ->z : string ->"z" : "z" - -}); - -// ----------------------------------------------------------------------------------------- - -interface Stuff { - field: number; ->field : number - - anotherField: string; ->anotherField : string -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { ->doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T ->s : { [K in keyof T & keyof Stuff]: T[K]; } - - if(Math.random() > 0.5) { ->Math.random() > 0.5 : boolean ->Math.random() : number ->Math.random : () => number ->Math : Math ->random : () => number ->0.5 : 0.5 - - return s as T ->s as T : T ->s : { [K in keyof T & keyof Stuff]: T[K]; } - - } else { - return s ->s : { [K in keyof T & keyof Stuff]: T[K]; } - } -} - -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->stuff1 : { field: 1; anotherField: "a"; } ->doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; } ->doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T ->{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } ->field : 1 ->1 : 1 ->anotherField : "a" ->'a' : "a" ->extra : number ->123 : 123 - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { ->doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] ->arr : { [K in keyof T & keyof Stuff]: T[K]; }[] - - if(Math.random() > 0.5) { ->Math.random() > 0.5 : boolean ->Math.random() : number ->Math.random : () => number ->Math : Math ->random : () => number ->0.5 : 0.5 - - return arr as T[] ->arr as T[] : T[] ->arr : { [K in keyof T & keyof Stuff]: T[K]; }[] - - } else { - return arr ->arr : { [K in keyof T & keyof Stuff]: T[K]; }[] - } -} - -const stuff2 = doStuffWithStuffArr([ ->stuff2 : { field: 1; anotherField: "a"; }[] ->doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; }[] ->doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] ->[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] - - { field: 1, anotherField: 'a', extra: 123 }, ->{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } ->field : 1 ->1 : 1 ->anotherField : "a" ->'a' : "a" ->extra : number ->123 : 123 - -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } ->XNumber : { x: number; } ->x : number - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T ->props : { [K in keyof T & "x"]: T[K]; } - -function bar(props: {x: number, y: string}) { ->bar : (props: { x: number; y: string;}) => { x: number; } ->props : { x: number; y: string; } ->x : number ->y : string - - return foo(props); // no error because lack of excess property check by design ->foo(props) : { x: number; } ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T ->props : { x: number; y: string; } -} - -const foo1 = foo({x: 1, y: 'foo'}); ->foo1 : { x: 1; } ->foo({x: 1, y: 'foo'}) : { x: 1; } ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T ->{x: 1, y: 'foo'} : { x: 1; y: string; } ->x : 1 ->1 : 1 ->y : string ->'foo' : "foo" - -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo2 : { x: 1; } ->foo({...{x: 1, y: 'foo'}}) : { x: 1; } ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T ->{...{x: 1, y: 'foo'}} : { x: 1; y: string; } ->{x: 1, y: 'foo'} : { x: 1; y: string; } ->x : 1 ->1 : 1 ->y : string ->'foo' : "foo" - -// ----------------------------------------------------------------------------------------- - -type NoErrWithOptProps = { x: number, y?: string } ->NoErrWithOptProps : { x: number; y?: string | undefined; } ->x : number ->y : string | undefined - -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T ->props : { [K in keyof T & keyof NoErrWithOptProps]: T[K]; } - -const baz1 = baz({x: 1}); ->baz1 : { x: 1; } ->baz({x: 1}) : { x: 1; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T ->{x: 1} : { x: 1; } ->x : 1 ->1 : 1 - -const baz2 = baz({x: 1, z: 123}); ->baz2 : { x: 1; } ->baz({x: 1, z: 123}) : { x: 1; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T ->{x: 1, z: 123} : { x: 1; z: number; } ->x : 1 ->1 : 1 ->z : number ->123 : 123 - -const baz3 = baz({x: 1, y: 'foo'}); ->baz3 : { x: 1; y: "foo"; } ->baz({x: 1, y: 'foo'}) : { x: 1; y: "foo"; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T ->{x: 1, y: 'foo'} : { x: 1; y: "foo"; } ->x : 1 ->1 : 1 ->y : "foo" ->'foo' : "foo" - -const baz4 = baz({x: 1, y: 'foo', z: 123}); ->baz4 : { x: 1; y: "foo"; } ->baz({x: 1, y: 'foo', z: 123}) : { x: 1; y: "foo"; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T ->{x: 1, y: 'foo', z: 123} : { x: 1; y: "foo"; z: number; } ->x : 1 ->1 : 1 ->y : "foo" ->'foo' : "foo" ->z : number ->123 : 123 - -// ----------------------------------------------------------------------------------------- - -interface WithNestedProp { - prop: string; ->prop : string - - nested: { ->nested : { prop: string; } - - prop: string; ->prop : string - } -} - -declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; ->withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T ->props : { [K in keyof T & keyof WithNestedProp]: T[K]; } - -const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); ->wnp : { prop: "foo"; nested: { prop: string; }; } ->withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; } ->withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T ->{prop: 'foo', nested: { prop: 'bar' }, extra: 10 } : { prop: "foo"; nested: { prop: string; }; extra: number; } ->prop : "foo" ->'foo' : "foo" ->nested : { prop: string; } ->{ prop: 'bar' } : { prop: string; } ->prop : string ->'bar' : "bar" ->extra : number ->10 : 10 - -// ----------------------------------------------------------------------------------------- - -type IsLiteralString = string extends T ? false : true; ->IsLiteralString : IsLiteralString ->false : false ->true : true - -interface ProvidedActor { - src: string; ->src : string - - logic: () => Promise; ->logic : () => Promise -} - -type DistributeActors = TActor extends { src: infer TSrc } ->DistributeActors : DistributeActors ->src : TSrc - - ? { - src: TSrc; ->src : TSrc - } - : never; - -interface MachineConfig { - types?: { ->types : { actors?: TActor | undefined; } | undefined - - actors?: TActor; ->actors : TActor | undefined - - }; - invoke: IsLiteralString extends true ->invoke : IsLiteralString extends true ? DistributeActors : { src: string; } ->true : true - - ? DistributeActors - : { - src: string; ->src : string - - }; -} - -declare function createXMachine< ->createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig - - const TConfig extends MachineConfig, - TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->types : { actors: ProvidedActor; } ->actors : ProvidedActor - ->(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; ->config : { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; } - -const child = () => Promise.resolve("foo"); ->child : () => Promise ->() => Promise.resolve("foo") : () => Promise ->Promise.resolve("foo") : Promise ->Promise.resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } ->Promise : PromiseConstructor ->resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } ->"foo" : "foo" - -const config = createXMachine({ ->config : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } ->createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10}) : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } ->createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig ->{ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } - - types: {} as { ->types : { actors: { src: "str"; logic: typeof child;}; } ->{} as { actors: { src: "str"; logic: typeof child; }; } : { actors: { src: "str"; logic: typeof child;}; } ->{} : {} - - actors: { ->actors : { src: "str"; logic: typeof child; } - - src: "str"; ->src : "str" - - logic: typeof child; ->logic : () => Promise ->child : () => Promise - - }; - }, - invoke: { ->invoke : { src: "str"; } ->{ src: "str", } : { src: "str"; } - - src: "str", ->src : "str" ->"str" : "str" - - }, - extra: 10 ->extra : number ->10 : 10 - -}); - -const config2 = createXMachine({ ->config2 : { invoke: { readonly src: "whatever"; }; } ->createXMachine({ invoke: { src: "whatever", }, extra: 10}) : { invoke: { readonly src: "whatever"; }; } ->createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig ->{ invoke: { src: "whatever", }, extra: 10} : { invoke: { src: "whatever"; }; extra: number; } - - invoke: { ->invoke : { src: "whatever"; } ->{ src: "whatever", } : { src: "whatever"; } - - src: "whatever", ->src : "whatever" ->"whatever" : "whatever" - - }, - extra: 10 ->extra : number ->10 : 10 - -}); - diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt index 654a3e5c75869..ee45f07758a30 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt @@ -1,25 +1,210 @@ -reverseMappedTypeLimitedConstraintWithIntersection1.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(15,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(28,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(39,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(53,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(57,64): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(63,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. + Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. + '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(68,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(81,25): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(92,25): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(94,35): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(107,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(152,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. +reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. -==== reverseMappedTypeLimitedConstraintWithIntersection1.ts (2 errors) ==== - type XNumber_ = { x: number } +==== reverseMappedTypeLimitedConstraintWithIntersection1.ts (13 errors) ==== + type StateConfig = { + entry?: TAction + states?: Record>; + }; - declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, + >(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + + const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + ~~~~~ +!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. +!!! related TS6500 reverseMappedTypeLimitedConstraintWithIntersection1.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' + }, + }, + extra: 12, + }); + + const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. + }); - foo_({x: 1, y: 'foo'}); - ~ -!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. // ----------------------------------------------------------------------------------------- - const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; - const checked_ = checkType_<{x: number, y: string}>()({ + const checked = checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", - z: "z", + z: "z", // undesirable property z is *not* allowed ~ !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. }); + + // ----------------------------------------------------------------------------------------- + + interface Stuff { + field: number; + anotherField: string; + } + + function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + + function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + ~~~~~~ +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +!!! error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +!!! error TS2322: '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. + } + } + + const stuff2 = doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. + ]) + + // ----------------------------------------------------------------------------------------- + + type XNumber = { x: number } + + declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; + + function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design + } + + const foo1 = foo({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + + // ----------------------------------------------------------------------------------------- + + type NoErrWithOptProps = { x: number, y?: string } + + declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; + + const baz1 = baz({x: 1}); + const baz2 = baz({x: 1, z: 123}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. + const baz3 = baz({x: 1, y: 'foo'}); + const baz4 = baz({x: 1, y: 'foo', z: 123}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. + + // ----------------------------------------------------------------------------------------- + + interface WithNestedProp { + prop: string; + nested: { + prop: string; + } + } + + declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + + const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. + + // ----------------------------------------------------------------------------------------- + + type IsLiteralString = string extends T ? false : true; + + interface ProvidedActor { + src: string; + logic: () => Promise; + } + + type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + + interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; + } + + declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, + >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + + const child = () => Promise.resolve("foo"); + + const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. + }); + + const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 + ~~~~~ +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. + }); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js index ad35f4aace2c9..58e25d6b1ee1b 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js @@ -1,30 +1,247 @@ //// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// //// [reverseMappedTypeLimitedConstraintWithIntersection1.ts] -type XNumber_ = { x: number } +type StateConfig = { + entry?: TAction + states?: Record>; +}; -declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); -foo_({x: 1, y: 'foo'}); // ----------------------------------------------------------------------------------------- -const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; -const checked_ = checkType_<{x: number, y: string}>()({ +const checked = checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", - z: "z", + z: "z", // undesirable property z is *not* allowed +}); + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +const stuff2 = doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +const foo1 = foo({x: 1, y: 'foo'}); + +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; + +const baz1 = baz({x: 1}); +const baz2 = baz({x: 1, z: 123}); +const baz3 = baz({x: 1, y: 'foo'}); +const baz4 = baz({x: 1, y: 'foo', z: 123}); + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; + +interface ProvidedActor { + src: string; + logic: () => Promise; +} + +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} + +declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + +const child = () => Promise.resolve("foo"); + +const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 +}); + +const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 }); //// [reverseMappedTypeLimitedConstraintWithIntersection1.js] "use strict"; -foo_({ x: 1, y: 'foo' }); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); +var inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); // ----------------------------------------------------------------------------------------- -var checkType_ = function () { return function (value) { return value; }; }; -var checked_ = checkType_()({ +var checkType = function () { return function (value) { return value; }; }; +var checked = checkType()({ x: 1, y: "y", - z: "z", + z: "z", // undesirable property z is *not* allowed +}); +function doStuffWithStuff(s) { + if (Math.random() > 0.5) { + return s; + } + else { + return s; + } +} +var stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); +function doStuffWithStuffArr(arr) { + if (Math.random() > 0.5) { + return arr; + } + else { + return arr; + } +} +var stuff2 = doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]); +function bar(props) { + return foo(props); // no error because lack of excess property check by design +} +var foo1 = foo({ x: 1, y: 'foo' }); +var foo2 = foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design +var baz1 = baz({ x: 1 }); +var baz2 = baz({ x: 1, z: 123 }); +var baz3 = baz({ x: 1, y: 'foo' }); +var baz4 = baz({ x: 1, y: 'foo', z: 123 }); +var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +var child = function () { return Promise.resolve("foo"); }; +var config = createXMachine({ + types: {}, + invoke: { + src: "str", + }, + extra: 10 +}); +var config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 }); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols index a488e609f13b8..66f1be0294f72 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols @@ -1,56 +1,466 @@ //// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// === reverseMappedTypeLimitedConstraintWithIntersection1.ts === -type XNumber_ = { x: number } ->XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) - -declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; ->foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 29)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) ->XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 42)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 51)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) ->XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 51)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 2, 22)) - -foo_({x: 1, y: 'foo'}); ->foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 29)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 4, 6)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 4, 11)) +type StateConfig = { +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) + + entry?: TAction +>entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 44)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) + + states?: Record>; +>states : Symbol(states, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 1, 17)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) + +}; + +declare function createMachine< +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 3, 2)) + + TConfig extends StateConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 6, 39)) + + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 6, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) + +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : Symbol(config, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 2)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 13)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 13)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 6, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) + +const inferredParams1 = createMachine({ +>inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 3, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 11, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 12, 11)) + + entry: "bar", +>entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 13, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 16, 4)) + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 20, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 3, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 20, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 21, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 22, 11)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 23, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 26, 4)) + +}); + // ----------------------------------------------------------------------------------------- -const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 5)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 20)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 29)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 20)) ->value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 42)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 52)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 29)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 20)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 29)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 52)) ->value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 42)) - -const checked_ = checkType_<{x: number, y: string}>()({ ->checked_ : Symbol(checked_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 5)) ->checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 5)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 29)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 39)) +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 5)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 19)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 28)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 19)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 41)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 51)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 28)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 19)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 28)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 51)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 41)) + +const checked = checkType<{x: number, y: string}>()({ +>checked : Symbol(checked, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 27)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 37)) x: 1 as number, ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 55)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 53)) y: "y", ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 11, 17)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 36, 17)) + + z: "z", // undesirable property z is *not* allowed +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 37, 9)) + +}); + +// ----------------------------------------------------------------------------------------- + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) + + field: number; +>field : Symbol(Stuff.field, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 43, 17)) + + anotherField: string; +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 44, 18)) +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 46, 1)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) +>s : Symbol(s, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 43)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 49)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 49)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return s as T +>s : Symbol(s, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 43)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) + + } else { + return s +>s : Symbol(s, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 43)) + } +} + +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>stuff1 : Symbol(stuff1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 5)) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 46, 1)) +>field : Symbol(field, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 33)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 43)) +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 62)) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 76)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) +>arr : Symbol(arr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 46)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 54)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 54)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return arr as T[] +>arr : Symbol(arr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 46)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) + + } else { + return arr +>arr : Symbol(arr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 46)) + } +} + +const stuff2 = doStuffWithStuffArr([ +>stuff2 : Symbol(stuff2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 66, 5)) +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 76)) + + { field: 1, anotherField: 'a', extra: 123 }, +>field : Symbol(field, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 67, 5)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 67, 15)) +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 67, 34)) + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 68, 2)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 16)) + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 68, 2)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 40)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 49)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 68, 2)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 49)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) + +function bar(props: {x: number, y: string}) { +>bar : Symbol(bar, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 90)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 13)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 21)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 31)) + + return foo(props); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 13)) +} + +const foo1 = foo({x: 1, y: 'foo'}); +>foo1 : Symbol(foo1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 80, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 80, 18)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 80, 23)) + +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo2 : Symbol(foo2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 5)) +>foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 22)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 27)) + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 40)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 26)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 37)) + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; +>baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 40)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 50)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 59)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 40)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 59)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) + +const baz1 = baz({x: 1}); +>baz1 : Symbol(baz1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 90, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 90, 18)) + +const baz2 = baz({x: 1, z: 123}); +>baz2 : Symbol(baz2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 91, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 91, 18)) +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 91, 23)) + +const baz3 = baz({x: 1, y: 'foo'}); +>baz3 : Symbol(baz3, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 92, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 92, 18)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 92, 23)) + +const baz4 = baz({x: 1, y: 'foo', z: 123}); +>baz4 : Symbol(baz4, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 5)) +>baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 18)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 23)) +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 33)) + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 43)) + + prop: string; +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 97, 26)) + + nested: { +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 98, 15)) + + prop: string; +>prop : Symbol(prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 99, 11)) + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 102, 1)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 43)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 58)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 67)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 43)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 67)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : Symbol(wnp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 102, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 40)) +>prop : Symbol(prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 50)) +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 65)) + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 79)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 21)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 21)) + +interface ProvidedActor { +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) + + src: string; +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 112, 25)) + + logic: () => Promise; +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 113, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 115, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 22)) +>src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 59)) + + ? { + src: TSrc; +>src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 118, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 59)) + } + : never; + +interface MachineConfig { +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 121, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) + + types?: { +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 55)) + + actors?: TActor; +>actors : Symbol(actors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 124, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) + + }; + invoke: IsLiteralString extends true +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 126, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 79)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) + + ? DistributeActors +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 115, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) + + : { + src: string; +>src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 129, 7)) + + }; +} + +declare function createXMachine< +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 132, 1)) + + const TConfig extends MachineConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 121, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 135, 46)) + + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 135, 46)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) +>types : Symbol(types, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 136, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 136, 59)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : Symbol(config, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 137, 2)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 137, 12)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 121, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 137, 12)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) + +const child = () => Promise.resolve("foo"); +>child : Symbol(child, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 139, 5)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) + +const config = createXMachine({ +>config : Symbol(config, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 141, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 132, 1)) + + types: {} as { +>types : Symbol(types, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 141, 31)) + + actors: { +>actors : Symbol(actors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 142, 16)) + + src: "str"; +>src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 143, 13)) + + logic: typeof child; +>logic : Symbol(logic, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 144, 17)) +>child : Symbol(child, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 139, 5)) + + }; + }, + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 147, 4)) + + src: "str", +>src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 148, 11)) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 150, 4)) + +}); + +const config2 = createXMachine({ +>config2 : Symbol(config2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 154, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 132, 1)) + + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 154, 32)) + + src: "whatever", +>src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 155, 11)) - z: "z", ->z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 12, 9)) + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 157, 4)) }); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types index 52b112a09a0d4..ac3541a4af9f2 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types @@ -1,40 +1,103 @@ //// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// === reverseMappedTypeLimitedConstraintWithIntersection1.ts === -type XNumber_ = { x: number } ->XNumber_ : { x: number; } ->x : number +type StateConfig = { +>StateConfig : StateConfig -declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; ->foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T ->props : { [K in keyof T & "x"]: T[K]; } + entry?: TAction +>entry : TAction | undefined + + states?: Record>; +>states : Record> | undefined + +}; + +declare function createMachine< +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] + + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; } + +const inferredParams1 = createMachine({ +>inferredParams1 : ["foo", StateConfig<"foo">] +>createMachine({ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,}) : ["foo", StateConfig<"foo">] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "bar", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "bar"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "bar"; }; } +>{ a: { entry: "bar", }, } : { a: { entry: "bar"; }; } + + a: { +>a : { entry: "bar"; } +>{ entry: "bar", } : { entry: "bar"; } + + entry: "bar", +>entry : "bar" +>"bar" : "bar" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine({ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,}) : ["foo", { entry: "foo"; states: { a: { entry: "foo"; }; }; }] +>createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] +>{ entry: "foo", states: { a: { entry: "foo", }, }, extra: 12,} : { entry: "foo"; states: { a: { entry: "foo"; }; }; extra: number; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + states: { +>states : { a: { entry: "foo"; }; } +>{ a: { entry: "foo", }, } : { a: { entry: "foo"; }; } + + a: { +>a : { entry: "foo"; } +>{ entry: "foo", } : { entry: "foo"; } + + entry: "foo", +>entry : "foo" +>"foo" : "foo" + + }, + }, + extra: 12, +>extra : number +>12 : 12 + +}); -foo_({x: 1, y: 'foo'}); ->foo_({x: 1, y: 'foo'}) : { x: 1; } ->foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T ->{x: 1, y: 'foo'} : { x: 1; y: string; } ->x : 1 ->1 : 1 ->y : string ->'foo' : "foo" // ----------------------------------------------------------------------------------------- -const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } >() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } >(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } >value : { [K in keyof U & keyof T]: U[K]; } >value : { [K in keyof U & keyof T]: U[K]; } -const checked_ = checkType_<{x: number, y: string}>()({ ->checked_ : { x: number; y: "y"; } ->checkType_<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z",}) : { x: number; y: "y"; } ->checkType_<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } ->checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +const checked = checkType<{x: number, y: string}>()({ +>checked : { x: number; y: "y"; } +>checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed}) : { x: number; y: "y"; } +>checkType<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } >x : number >y : string ->{ x: 1 as number, y: "y", z: "z",} : { x: number; y: "y"; z: string; } +>{ x: 1 as number, y: "y", z: "z", // undesirable property z is *not* allowed} : { x: number; y: "y"; z: string; } x: 1 as number, >x : number @@ -45,9 +108,342 @@ const checked_ = checkType_<{x: number, y: string}>()({ >y : "y" >"y" : "y" - z: "z", + z: "z", // undesirable property z is *not* allowed >z : string >"z" : "z" }); +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; +>field : number + + anotherField: string; +>anotherField : string +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T +>s : { [K in keyof T & keyof Stuff]: T[K]; } + + if(Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return s as T +>s as T : T +>s : { [K in keyof T & keyof Stuff]: T[K]; } + + } else { + return s +>s : { [K in keyof T & keyof Stuff]: T[K]; } + } +} + +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>stuff1 : { field: 1; anotherField: "a"; } +>doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; } +>doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T +>{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>'a' : "a" +>extra : number +>123 : 123 + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + + if(Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return arr as T[] +>arr as T[] : T[] +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + + } else { + return arr +>arr : { [K in keyof T & keyof Stuff]: T[K]; }[] + } +} + +const stuff2 = doStuffWithStuffArr([ +>stuff2 : { field: 1; anotherField: "a"; }[] +>doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; }[] +>doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] +>[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] + + { field: 1, anotherField: 'a', extra: 123 }, +>{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } +>field : 1 +>1 : 1 +>anotherField : "a" +>'a' : "a" +>extra : number +>123 : 123 + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : { x: number; } +>x : number + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +>props : { [K in keyof T & "x"]: T[K]; } + +function bar(props: {x: number, y: string}) { +>bar : (props: { x: number; y: string;}) => { x: number; } +>props : { x: number; y: string; } +>x : number +>y : string + + return foo(props); // no error because lack of excess property check by design +>foo(props) : { x: number; } +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +>props : { x: number; y: string; } +} + +const foo1 = foo({x: 1, y: 'foo'}); +>foo1 : { x: 1; } +>foo({x: 1, y: 'foo'}) : { x: 1; } +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo2 : { x: 1; } +>foo({...{x: 1, y: 'foo'}}) : { x: 1; } +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +>{...{x: 1, y: 'foo'}} : { x: 1; y: string; } +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : { x: number; y?: string | undefined; } +>x : number +>y : string | undefined + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +>props : { [K in keyof T & keyof NoErrWithOptProps]: T[K]; } + +const baz1 = baz({x: 1}); +>baz1 : { x: 1; } +>baz({x: 1}) : { x: 1; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +>{x: 1} : { x: 1; } +>x : 1 +>1 : 1 + +const baz2 = baz({x: 1, z: 123}); +>baz2 : { x: 1; } +>baz({x: 1, z: 123}) : { x: 1; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +>{x: 1, z: 123} : { x: 1; z: number; } +>x : 1 +>1 : 1 +>z : number +>123 : 123 + +const baz3 = baz({x: 1, y: 'foo'}); +>baz3 : { x: 1; y: "foo"; } +>baz({x: 1, y: 'foo'}) : { x: 1; y: "foo"; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +>{x: 1, y: 'foo'} : { x: 1; y: "foo"; } +>x : 1 +>1 : 1 +>y : "foo" +>'foo' : "foo" + +const baz4 = baz({x: 1, y: 'foo', z: 123}); +>baz4 : { x: 1; y: "foo"; } +>baz({x: 1, y: 'foo', z: 123}) : { x: 1; y: "foo"; } +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +>{x: 1, y: 'foo', z: 123} : { x: 1; y: "foo"; z: number; } +>x : 1 +>1 : 1 +>y : "foo" +>'foo' : "foo" +>z : number +>123 : 123 + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; +>prop : string + + nested: { +>nested : { prop: string; } + + prop: string; +>prop : string + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T +>props : { [K in keyof T & keyof WithNestedProp]: T[K]; } + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }) : { prop: "foo"; nested: { prop: string; }; } +>withNestedProp : (props: { [K in keyof T & keyof WithNestedProp]: T[K]; }) => T +>{prop: 'foo', nested: { prop: 'bar' }, extra: 10 } : { prop: "foo"; nested: { prop: string; }; extra: number; } +>prop : "foo" +>'foo' : "foo" +>nested : { prop: string; } +>{ prop: 'bar' } : { prop: string; } +>prop : string +>'bar' : "bar" +>extra : number +>10 : 10 + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : IsLiteralString +>false : false +>true : true + +interface ProvidedActor { + src: string; +>src : string + + logic: () => Promise; +>logic : () => Promise +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : DistributeActors +>src : TSrc + + ? { + src: TSrc; +>src : TSrc + } + : never; + +interface MachineConfig { + types?: { +>types : { actors?: TActor | undefined; } | undefined + + actors?: TActor; +>actors : TActor | undefined + + }; + invoke: IsLiteralString extends true +>invoke : IsLiteralString extends true ? DistributeActors : { src: string; } +>true : true + + ? DistributeActors + : { + src: string; +>src : string + + }; +} + +declare function createXMachine< +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig + + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>types : { actors: ProvidedActor; } +>actors : ProvidedActor + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; } + +const child = () => Promise.resolve("foo"); +>child : () => Promise +>() => Promise.resolve("foo") : () => Promise +>Promise.resolve("foo") : Promise +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } +>Promise : PromiseConstructor +>resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } +>"foo" : "foo" + +const config = createXMachine({ +>config : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } +>createXMachine({ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10}) : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { readonly src: "str"; }; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ types: {} as { actors: { src: "str"; logic: typeof child; }; }, invoke: { src: "str", }, extra: 10} : { types: { actors: { src: "str"; logic: typeof child;}; }; invoke: { src: "str"; }; extra: number; } + + types: {} as { +>types : { actors: { src: "str"; logic: typeof child;}; } +>{} as { actors: { src: "str"; logic: typeof child; }; } : { actors: { src: "str"; logic: typeof child;}; } +>{} : {} + + actors: { +>actors : { src: "str"; logic: typeof child; } + + src: "str"; +>src : "str" + + logic: typeof child; +>logic : () => Promise +>child : () => Promise + + }; + }, + invoke: { +>invoke : { src: "str"; } +>{ src: "str", } : { src: "str"; } + + src: "str", +>src : "str" +>"str" : "str" + + }, + extra: 10 +>extra : number +>10 : 10 + +}); + +const config2 = createXMachine({ +>config2 : { invoke: { readonly src: "whatever"; }; } +>createXMachine({ invoke: { src: "whatever", }, extra: 10}) : { invoke: { readonly src: "whatever"; }; } +>createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor; }; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig +>{ invoke: { src: "whatever", }, extra: 10} : { invoke: { src: "whatever"; }; extra: number; } + + invoke: { +>invoke : { src: "whatever"; } +>{ src: "whatever", } : { src: "whatever"; } + + src: "whatever", +>src : "whatever" +>"whatever" : "whatever" + + }, + extra: 10 +>extra : number +>10 : 10 + +}); + diff --git a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts deleted file mode 100644 index c86372d68ece2..0000000000000 --- a/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts +++ /dev/null @@ -1,163 +0,0 @@ -// @strict: true -// @lib: esnext - -type StateConfig = { - entry?: TAction - states?: Record>; -}; - -declare function createMachine< - TConfig extends StateConfig, - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; - -const inferredParams1 = createMachine({ - entry: "foo", - states: { - a: { - entry: "bar", - }, - }, - extra: 12, -}); - -const inferredParams2 = createMachine({ - entry: "foo", - states: { - a: { - entry: "foo", - }, - }, - extra: 12, -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; - -const checked = checkType<{x: number, y: string}>()({ - x: 1 as number, - y: "y", - z: "z", // undesirable property z is *not* allowed -}); - -// ----------------------------------------------------------------------------------------- - -interface Stuff { - field: number; - anotherField: string; -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { - if(Math.random() > 0.5) { - return s as T - } else { - return s - } -} - -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { - if(Math.random() > 0.5) { - return arr as T[] - } else { - return arr - } -} - -const stuff2 = doStuffWithStuffArr([ - { field: 1, anotherField: 'a', extra: 123 }, -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; - -function bar(props: {x: number, y: string}) { - return foo(props); // no error because lack of excess property check by design -} - -const foo1 = foo({x: 1, y: 'foo'}); - -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design - -// ----------------------------------------------------------------------------------------- - -type NoErrWithOptProps = { x: number, y?: string } - -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; - -const baz1 = baz({x: 1}); -const baz2 = baz({x: 1, z: 123}); -const baz3 = baz({x: 1, y: 'foo'}); -const baz4 = baz({x: 1, y: 'foo', z: 123}); - -// ----------------------------------------------------------------------------------------- - -interface WithNestedProp { - prop: string; - nested: { - prop: string; - } -} - -declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; - -const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); - -// ----------------------------------------------------------------------------------------- - -type IsLiteralString = string extends T ? false : true; - -interface ProvidedActor { - src: string; - logic: () => Promise; -} - -type DistributeActors = TActor extends { src: infer TSrc } - ? { - src: TSrc; - } - : never; - -interface MachineConfig { - types?: { - actors?: TActor; - }; - invoke: IsLiteralString extends true - ? DistributeActors - : { - src: string; - }; -} - -declare function createXMachine< - const TConfig extends MachineConfig, - TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; - -const child = () => Promise.resolve("foo"); - -const config = createXMachine({ - types: {} as { - actors: { - src: "str"; - logic: typeof child; - }; - }, - invoke: { - src: "str", - }, - extra: 10 -}); - -const config2 = createXMachine({ - invoke: { - src: "whatever", - }, - extra: 10 -}); diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts index 4db2da39172db..c86372d68ece2 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts @@ -1,17 +1,163 @@ // @strict: true +// @lib: esnext -type XNumber_ = { x: number } +type StateConfig = { + entry?: TAction + states?: Record>; +}; -declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +declare function createMachine< + TConfig extends StateConfig, + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; + +const inferredParams1 = createMachine({ + entry: "foo", + states: { + a: { + entry: "bar", + }, + }, + extra: 12, +}); + +const inferredParams2 = createMachine({ + entry: "foo", + states: { + a: { + entry: "foo", + }, + }, + extra: 12, +}); -foo_({x: 1, y: 'foo'}); // ----------------------------------------------------------------------------------------- -const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; -const checked_ = checkType_<{x: number, y: string}>()({ +const checked = checkType<{x: number, y: string}>()({ x: 1 as number, y: "y", - z: "z", + z: "z", // undesirable property z is *not* allowed +}); + +// ----------------------------------------------------------------------------------------- + +interface Stuff { + field: number; + anotherField: string; +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { + if(Math.random() > 0.5) { + return s as T + } else { + return s + } +} + +const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { + if(Math.random() > 0.5) { + return arr as T[] + } else { + return arr + } +} + +const stuff2 = doStuffWithStuffArr([ + { field: 1, anotherField: 'a', extra: 123 }, +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; + +function bar(props: {x: number, y: string}) { + return foo(props); // no error because lack of excess property check by design +} + +const foo1 = foo({x: 1, y: 'foo'}); + +const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; + +const baz1 = baz({x: 1}); +const baz2 = baz({x: 1, z: 123}); +const baz3 = baz({x: 1, y: 'foo'}); +const baz4 = baz({x: 1, y: 'foo', z: 123}); + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { + prop: string; + nested: { + prop: string; + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; + +interface ProvidedActor { + src: string; + logic: () => Promise; +} + +type DistributeActors = TActor extends { src: infer TSrc } + ? { + src: TSrc; + } + : never; + +interface MachineConfig { + types?: { + actors?: TActor; + }; + invoke: IsLiteralString extends true + ? DistributeActors + : { + src: string; + }; +} + +declare function createXMachine< + const TConfig extends MachineConfig, + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; + +const child = () => Promise.resolve("foo"); + +const config = createXMachine({ + types: {} as { + actors: { + src: "str"; + logic: typeof child; + }; + }, + invoke: { + src: "str", + }, + extra: 10 +}); + +const config2 = createXMachine({ + invoke: { + src: "whatever", + }, + extra: 10 }); From 1271786376183b24765d5427015fe8e864e0271d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 10:41:34 +0100 Subject: [PATCH 07/13] add extra test cases to showcase how constraint limiting is important to satisfy the constraint of the type param --- ...onstraintWithFilteringNameType1.errors.txt | 9 ++++++ ...edConstraintWithFilteringNameType1.symbols | 32 +++++++++++++++++++ ...itedConstraintWithFilteringNameType1.types | 25 +++++++++++++++ ...itedConstraintWithIntersection1.errors.txt | 9 ++++++ ...dTypeLimitedConstraintWithIntersection1.js | 14 ++++++++ ...LimitedConstraintWithIntersection1.symbols | 30 +++++++++++++++++ ...peLimitedConstraintWithIntersection1.types | 25 +++++++++++++++ ...LimitedConstraintWithFilteringNameType1.ts | 9 ++++++ ...dTypeLimitedConstraintWithIntersection1.ts | 9 ++++++ 9 files changed, 162 insertions(+) diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt index c1c2943c07df6..b4838a6ef0975 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt @@ -31,4 +31,13 @@ reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts(17,3): error TS2353: z: "z", }; const checked2 = checkType<{ x: number; y: string }>()(objChecked); + + declare function fn1>(obj: { + [K in keyof T as K extends "a" ? K : never]: T[K]; + }): T; + const obj1 = { + a: 42, + b: true, + }; + const result1 = fn1(obj1); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols index d3d9e46d13035..48e9df66898c2 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols @@ -93,3 +93,35 @@ const checked2 = checkType<{ x: number; y: string }>()(objChecked); >y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 39)) >objChecked : Symbol(objChecked, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 18, 5)) +declare function fn1>(obj: { +>fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 67)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 25, 21)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 25, 55)) + + [K in keyof T as K extends "a" ? K : never]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 26, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 25, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 26, 3)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 26, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 25, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 26, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 25, 21)) + +const obj1 = { +>obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 28, 5)) + + a: 42, +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 28, 14)) + + b: true, +>b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 29, 8)) + +}; +const result1 = fn1(obj1); +>result1 : Symbol(result1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 32, 5)) +>fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 67)) +>obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 28, 5)) + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types index fa21d7465d397..c84ef867ce6d3 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types @@ -97,3 +97,28 @@ const checked2 = checkType<{ x: number; y: string }>()(objChecked); >y : string >objChecked : { x: number; y: string; z: string; } +declare function fn1>(obj: { +>fn1 : >(obj: { [K in keyof T as K extends "a" ? K : never]: T[K]; }) => T +>obj : { [K in keyof T as K extends "a" ? K : never]: T[K]; } + + [K in keyof T as K extends "a" ? K : never]: T[K]; +}): T; +const obj1 = { +>obj1 : { a: number; b: boolean; } +>{ a: 42, b: true,} : { a: number; b: boolean; } + + a: 42, +>a : number +>42 : 42 + + b: true, +>b : boolean +>true : true + +}; +const result1 = fn1(obj1); +>result1 : { a: number; } +>fn1(obj1) : { a: number; } +>fn1 : >(obj: { [K in keyof T as K extends "a" ? K : never]: T[K]; }) => T +>obj1 : { a: number; b: boolean; } + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt index ee45f07758a30..abbe0d2a84c8e 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt @@ -207,4 +207,13 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. }); + + declare function fn1>(obj: { + [K in keyof T & "a"]: T[K]; + }): T; + const obj1 = { + a: 42, + b: true, + }; + const result1 = fn1(obj1); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js index 58e25d6b1ee1b..e3589be404641 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js @@ -161,6 +161,15 @@ const config2 = createXMachine({ }, extra: 10 }); + +declare function fn1>(obj: { + [K in keyof T & "a"]: T[K]; +}): T; +const obj1 = { + a: 42, + b: true, +}; +const result1 = fn1(obj1); //// [reverseMappedTypeLimitedConstraintWithIntersection1.js] @@ -245,3 +254,8 @@ var config2 = createXMachine({ }, extra: 10 }); +var obj1 = { + a: 42, + b: true, +}; +var result1 = fn1(obj1); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols index 66f1be0294f72..b0573b1023deb 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols @@ -464,3 +464,33 @@ const config2 = createXMachine({ }); +declare function fn1>(obj: { +>fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 159, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 55)) + + [K in keyof T & "a"]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 162, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 162, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) + +const obj1 = { +>obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 5)) + + a: 42, +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 14)) + + b: true, +>b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 165, 8)) + +}; +const result1 = fn1(obj1); +>result1 : Symbol(result1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 168, 5)) +>fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 159, 3)) +>obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 5)) + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types index ac3541a4af9f2..c2b1ca88fc67d 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types @@ -447,3 +447,28 @@ const config2 = createXMachine({ }); +declare function fn1>(obj: { +>fn1 : >(obj: { [K in keyof T & "a"]: T[K]; }) => T +>obj : { [K in keyof T & "a"]: T[K]; } + + [K in keyof T & "a"]: T[K]; +}): T; +const obj1 = { +>obj1 : { a: number; b: boolean; } +>{ a: 42, b: true,} : { a: number; b: boolean; } + + a: 42, +>a : number +>42 : 42 + + b: true, +>b : boolean +>true : true + +}; +const result1 = fn1(obj1); +>result1 : { a: number; } +>fn1(obj1) : { a: number; } +>fn1 : >(obj: { [K in keyof T & "a"]: T[K]; }) => T +>obj1 : { a: number; b: boolean; } + diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts index 37f3b56dbcad3..8659f2db1ba2d 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts @@ -25,3 +25,12 @@ const objChecked = { z: "z", }; const checked2 = checkType<{ x: number; y: string }>()(objChecked); + +declare function fn1>(obj: { + [K in keyof T as K extends "a" ? K : never]: T[K]; +}): T; +const obj1 = { + a: 42, + b: true, +}; +const result1 = fn1(obj1); diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts index c86372d68ece2..893360ad9b588 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts @@ -161,3 +161,12 @@ const config2 = createXMachine({ }, extra: 10 }); + +declare function fn1>(obj: { + [K in keyof T & "a"]: T[K]; +}): T; +const obj1 = { + a: 42, + b: true, +}; +const result1 = fn1(obj1); From 6c74957f3a7504b598fd0877ea9bb801dd056505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 10:45:07 +0100 Subject: [PATCH 08/13] showcase additional fix with mixed union and intersection --- ...itedConstraintWithIntersection1.errors.txt | 10 ++++++ ...dTypeLimitedConstraintWithIntersection1.js | 16 +++++++++ ...LimitedConstraintWithIntersection1.symbols | 33 +++++++++++++++++++ ...peLimitedConstraintWithIntersection1.types | 29 ++++++++++++++++ ...dTypeLimitedConstraintWithIntersection1.ts | 10 ++++++ 5 files changed, 98 insertions(+) diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt index abbe0d2a84c8e..a449ffb14b6d4 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt @@ -216,4 +216,14 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj b: true, }; const result1 = fn1(obj1); + + declare function fn2>(obj: { + [K in (keyof T & "a") | "b"]: T[K]; + }): T; + const obj2 = { + a: 42, + b: 100, + c: true, + }; + const result2 = fn2(obj2); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js index e3589be404641..0d9ba7239290b 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js @@ -170,6 +170,16 @@ const obj1 = { b: true, }; const result1 = fn1(obj1); + +declare function fn2>(obj: { + [K in (keyof T & "a") | "b"]: T[K]; +}): T; +const obj2 = { + a: 42, + b: 100, + c: true, +}; +const result2 = fn2(obj2); //// [reverseMappedTypeLimitedConstraintWithIntersection1.js] @@ -259,3 +269,9 @@ var obj1 = { b: true, }; var result1 = fn1(obj1); +var obj2 = { + a: 42, + b: 100, + c: true, +}; +var result2 = fn2(obj2); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols index b0573b1023deb..762f94ecc7e31 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols @@ -494,3 +494,36 @@ const result1 = fn1(obj1); >fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 159, 3)) >obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 5)) +declare function fn2>(obj: { +>fn2 : Symbol(fn2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 168, 26)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 55)) + + [K in (keyof T & "a") | "b"]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 171, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 171, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) + +const obj2 = { +>obj2 : Symbol(obj2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 173, 5)) + + a: 42, +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 173, 14)) + + b: 100, +>b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 174, 8)) + + c: true, +>c : Symbol(c, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 175, 9)) + +}; +const result2 = fn2(obj2); +>result2 : Symbol(result2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 178, 5)) +>fn2 : Symbol(fn2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 168, 26)) +>obj2 : Symbol(obj2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 173, 5)) + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types index c2b1ca88fc67d..e5bba36010ccd 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types @@ -472,3 +472,32 @@ const result1 = fn1(obj1); >fn1 : >(obj: { [K in keyof T & "a"]: T[K]; }) => T >obj1 : { a: number; b: boolean; } +declare function fn2>(obj: { +>fn2 : >(obj: { [K in "b" | (keyof T & "a")]: T[K]; }) => T +>obj : { [K in "b" | (keyof T & "a")]: T[K]; } + + [K in (keyof T & "a") | "b"]: T[K]; +}): T; +const obj2 = { +>obj2 : { a: number; b: number; c: boolean; } +>{ a: 42, b: 100, c: true,} : { a: number; b: number; c: boolean; } + + a: 42, +>a : number +>42 : 42 + + b: 100, +>b : number +>100 : 100 + + c: true, +>c : boolean +>true : true + +}; +const result2 = fn2(obj2); +>result2 : { a: number; b: number; } +>fn2(obj2) : { a: number; b: number; } +>fn2 : >(obj: { [K in "b" | (keyof T & "a")]: T[K]; }) => T +>obj2 : { a: number; b: number; c: boolean; } + diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts index 893360ad9b588..6d1f88562f55d 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts @@ -170,3 +170,13 @@ const obj1 = { b: true, }; const result1 = fn1(obj1); + +declare function fn2>(obj: { + [K in (keyof T & "a") | "b"]: T[K]; +}): T; +const obj2 = { + a: 42, + b: 100, + c: true, +}; +const result2 = fn2(obj2); From 998b96b8b735e5653f496d6484e320d6485619f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 10:51:21 +0100 Subject: [PATCH 09/13] add tests for combined intersection limiting and name type limiting --- ...onstraintWithFilteringNameType1.errors.txt | 12 +++++ ...edConstraintWithFilteringNameType1.symbols | 54 +++++++++++++++++++ ...itedConstraintWithFilteringNameType1.types | 44 +++++++++++++++ ...LimitedConstraintWithFilteringNameType1.ts | 12 +++++ 4 files changed, 122 insertions(+) diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt index b4838a6ef0975..257e19303c75a 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.errors.txt @@ -40,4 +40,16 @@ reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts(17,3): error TS2353: b: true, }; const result1 = fn1(obj1); + + declare function fn2(obj: { + [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; + }): T; + const obj2 = { a: 1, b: 2, c: 3 }; + const result2 = fn2(obj2); + + declare function fn3(obj: { + [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; + }): T; + const obj3 = { a: 1, b: 2, c: 3 }; + const result3 = fn3(obj3); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols index 48e9df66898c2..de8519fb4e639 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.symbols @@ -125,3 +125,57 @@ const result1 = fn1(obj1); >fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 23, 67)) >obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 28, 5)) +declare function fn2(obj: { +>fn2 : Symbol(fn2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 32, 26)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 34, 21)) +>obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 34, 24)) + + [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 35, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 34, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 35, 3)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 35, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 34, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 35, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 34, 21)) + +const obj2 = { a: 1, b: 2, c: 3 }; +>obj2 : Symbol(obj2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 37, 5)) +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 37, 14)) +>b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 37, 20)) +>c : Symbol(c, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 37, 26)) + +const result2 = fn2(obj2); +>result2 : Symbol(result2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 38, 5)) +>fn2 : Symbol(fn2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 32, 26)) +>obj2 : Symbol(obj2, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 37, 5)) + +declare function fn3(obj: { +>fn3 : Symbol(fn3, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 38, 26)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 40, 21)) +>obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 40, 24)) + + [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 41, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 40, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 41, 3)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 41, 3)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 40, 21)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 41, 3)) + +}): T; +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 40, 21)) + +const obj3 = { a: 1, b: 2, c: 3 }; +>obj3 : Symbol(obj3, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 43, 5)) +>a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 43, 14)) +>b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 43, 20)) +>c : Symbol(c, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 43, 26)) + +const result3 = fn3(obj3); +>result3 : Symbol(result3, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 44, 5)) +>fn3 : Symbol(fn3, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 38, 26)) +>obj3 : Symbol(obj3, Decl(reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts, 43, 5)) + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types index c84ef867ce6d3..3b114c4ffec3f 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithFilteringNameType1.types @@ -122,3 +122,47 @@ const result1 = fn1(obj1); >fn1 : >(obj: { [K in keyof T as K extends "a" ? K : never]: T[K]; }) => T >obj1 : { a: number; b: boolean; } +declare function fn2(obj: { +>fn2 : (obj: { [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; }) => T +>obj : { [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; } + + [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; +}): T; +const obj2 = { a: 1, b: 2, c: 3 }; +>obj2 : { a: number; b: number; c: number; } +>{ a: 1, b: 2, c: 3 } : { a: number; b: number; c: number; } +>a : number +>1 : 1 +>b : number +>2 : 2 +>c : number +>3 : 3 + +const result2 = fn2(obj2); +>result2 : { a: number; } +>fn2(obj2) : { a: number; } +>fn2 : (obj: { [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; }) => T +>obj2 : { a: number; b: number; c: number; } + +declare function fn3(obj: { +>fn3 : (obj: { [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; }) => T +>obj : { [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; } + + [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; +}): T; +const obj3 = { a: 1, b: 2, c: 3 }; +>obj3 : { a: number; b: number; c: number; } +>{ a: 1, b: 2, c: 3 } : { a: number; b: number; c: number; } +>a : number +>1 : 1 +>b : number +>2 : 2 +>c : number +>3 : 3 + +const result3 = fn3(obj3); +>result3 : { a: number; } +>fn3(obj3) : { a: number; } +>fn3 : (obj: { [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; }) => T +>obj3 : { a: number; b: number; c: number; } + diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts index 8659f2db1ba2d..28a3748c0b8c6 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithFilteringNameType1.ts @@ -34,3 +34,15 @@ const obj1 = { b: true, }; const result1 = fn1(obj1); + +declare function fn2(obj: { + [K in keyof T & ("a" | "b") as K extends "a" | "c" ? K : never]: T[K]; +}): T; +const obj2 = { a: 1, b: 2, c: 3 }; +const result2 = fn2(obj2); + +declare function fn3(obj: { + [K in keyof T & ("a" | "c") as K extends "a" | "b" ? K : never]: T[K]; +}): T; +const obj3 = { a: 1, b: 2, c: 3 }; +const result3 = fn3(obj3); From 171ee93d552e9296062df86054c2c8f424fd0584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 11:03:59 +0100 Subject: [PATCH 10/13] improve comments and variable names --- src/compiler/checker.ts | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9c1e22e052235..ee52913ed189f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13667,11 +13667,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } - // If the original mapped type had an intersection constraint we extract its components, - // and we make an attempt to do so even if the intersection has been reduced to a union. - // This entire process allows us to possibly retrieve the filtering type literals. - // e.g. { [K in keyof U & ("a" | "b") ] } -> "a" | "b" - function getLimitedConstraint(type: ReverseMappedType) { + // If the original mapped type had an union/intersection constraint + // there is a chance that it includes an intersection that could limit what members are allowed + function getReverseMappedTypeMembersLimitingConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); if (constraint === type.constraintType) { return; @@ -13692,16 +13690,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; const members = createSymbolTable(); - const limitedConstraint = getLimitedConstraint(type); + const membersLimitingConstraint = getReverseMappedTypeMembersLimitingConstraint(type); const nameType = getNameTypeFromMappedType(type.mappedType); for (const prop of getPropertiesOfType(type.source)) { - // In case of a reverse mapped type with an intersection constraint, if we were able to - // extract the filtering type literals we skip those properties that are not assignable to them, - // because the extra properties wouldn't get through the application of the mapped type anyway - if (limitedConstraint || nameType) { + // we skip those properties that are not assignable to either of those "limiters" + // the extra properties wouldn't get through the application of the mapped type anyway + // and their inferred type might not satisfy the type parameter's constraint + // which, in turn, could fail the check if the inferred type is assignable to its constraint + // + // inferring `{ a: number; b: string }` wouldn't satisfy T's constraint so b has to be skipped over here + // + // function fn>({ [K in keyof T & "a"]: T[K] }): T + // const obj = { a: 1, b: '2' }; + // fn(obj); + if (membersLimitingConstraint || nameType) { const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); - if (limitedConstraint && !isTypeAssignableTo(propertyNameType, limitedConstraint)) { + if (membersLimitingConstraint && !isTypeAssignableTo(propertyNameType, membersLimitingConstraint)) { continue; } if (nameType) { From 5f3cf18d722b1e71975876527c0f6e0b3c1d3952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 11:09:12 +0100 Subject: [PATCH 11/13] replace record with object --- src/compiler/checker.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ee52913ed189f..92d702538d015 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2008,6 +2008,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var numberOrBigIntType = getUnionType([numberType, bigintType]); var templateConstraintType = getUnionType([stringType, numberType, booleanType, bigintType, nullType, undefinedType]) as UnionType; var numericStringType = getTemplateLiteralType(["", ""], [numberType]); // The `${number}` type + var keyofConstraintObject = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, [stringType, numberType, esSymbolType].map(t => createIndexInfo(t, unknownType, /*isReadonly*/ false))); // { [k: string | number | symbol]: unknown; } var restrictiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(t as TypeParameter) : t, () => "(restrictive mapper)"); var permissiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? wildcardType : t, () => "(permissive mapper)"); @@ -13674,12 +13675,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (constraint === type.constraintType) { return; } - const recordSymbol = getGlobalRecordSymbol(); - if (!recordSymbol) { - return; - } - const keyofConstraintRecord = getTypeAliasInstantiation(recordSymbol, [keyofConstraintType, unknownType]); - const mapper = appendTypeMapping(type.mappedType.mapper, type.constraintType.type, keyofConstraintRecord); + const mapper = appendTypeMapping(type.mappedType.mapper, type.constraintType.type, keyofConstraintObject); return getBaseConstraintOrType(instantiateType(constraint, mapper)); } From 59b6549d965ffcb63b57be21619238c8128c1002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 11:13:20 +0100 Subject: [PATCH 12/13] fix format --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 92d702538d015..4ddaa3cb97932 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13668,7 +13668,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } - // If the original mapped type had an union/intersection constraint + // If the original mapped type had an union/intersection constraint // there is a chance that it includes an intersection that could limit what members are allowed function getReverseMappedTypeMembersLimitingConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); @@ -13696,7 +13696,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // which, in turn, could fail the check if the inferred type is assignable to its constraint // // inferring `{ a: number; b: string }` wouldn't satisfy T's constraint so b has to be skipped over here - // + // // function fn>({ [K in keyof T & "a"]: T[K] }): T // const obj = { a: 1, b: '2' }; // fn(obj); From 37521a7e73767432bad9f35edea0fa0a460adbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 31 Dec 2023 13:08:10 +0100 Subject: [PATCH 13/13] Remove what got carved out to a separate bug fixing PR --- src/compiler/checker.ts | 42 +- ...ppedTypeIntersectionConstraint.errors.txt} | 94 ++-- ...everseMappedTypeIntersectionConstraint.js} | 85 ++- ...seMappedTypeIntersectionConstraint.symbols | 491 ++++++++++++++++ ...rseMappedTypeIntersectionConstraint.types} | 156 ++---- ...erseMappedTypeLimitedConstraint.errors.txt | 24 + .../reverseMappedTypeLimitedConstraint.js | 28 + ...reverseMappedTypeLimitedConstraint.symbols | 55 ++ .../reverseMappedTypeLimitedConstraint.types | 52 ++ ...LimitedConstraintWithIntersection1.symbols | 529 ------------------ ...everseMappedTypeIntersectionConstraint.ts} | 52 +- .../reverseMappedTypeLimitedConstraint.ts | 15 + 12 files changed, 843 insertions(+), 780 deletions(-) rename tests/baselines/reference/{reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt => reverseMappedTypeIntersectionConstraint.errors.txt} (62%) rename tests/baselines/reference/{reverseMappedTypeLimitedConstraintWithIntersection1.js => reverseMappedTypeIntersectionConstraint.js} (76%) create mode 100644 tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols rename tests/baselines/reference/{reverseMappedTypeLimitedConstraintWithIntersection1.types => reverseMappedTypeIntersectionConstraint.types} (78%) create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraint.js create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraint.types delete mode 100644 tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols rename tests/cases/compiler/{reverseMappedTypeLimitedConstraintWithIntersection1.ts => reverseMappedTypeIntersectionConstraint.ts} (81%) create mode 100644 tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4ddaa3cb97932..2bce201e7e35b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2008,7 +2008,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var numberOrBigIntType = getUnionType([numberType, bigintType]); var templateConstraintType = getUnionType([stringType, numberType, booleanType, bigintType, nullType, undefinedType]) as UnionType; var numericStringType = getTemplateLiteralType(["", ""], [numberType]); // The `${number}` type - var keyofConstraintObject = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, [stringType, numberType, esSymbolType].map(t => createIndexInfo(t, unknownType, /*isReadonly*/ false))); // { [k: string | number | symbol]: unknown; } var restrictiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(t as TypeParameter) : t, () => "(restrictive mapper)"); var permissiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? wildcardType : t, () => "(permissive mapper)"); @@ -13668,15 +13667,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } - // If the original mapped type had an union/intersection constraint - // there is a chance that it includes an intersection that could limit what members are allowed - function getReverseMappedTypeMembersLimitingConstraint(type: ReverseMappedType) { + // If the original mapped type had an intersection constraint we extract its components, + // and we make an attempt to do so even if the intersection has been reduced to a union. + // This entire process allows us to possibly retrieve the filtering type literals. + // e.g. { [K in keyof U & ("a" | "b") ] } -> "a" | "b" + function getLimitedConstraint(type: ReverseMappedType) { const constraint = getConstraintTypeFromMappedType(type.mappedType); - if (constraint === type.constraintType) { + if (!(constraint.flags & TypeFlags.Union || constraint.flags & TypeFlags.Intersection)) { return; } - const mapper = appendTypeMapping(type.mappedType.mapper, type.constraintType.type, keyofConstraintObject); - return getBaseConstraintOrType(instantiateType(constraint, mapper)); + const origin = (constraint.flags & TypeFlags.Union) ? (constraint as UnionType).origin : (constraint as IntersectionType); + if (!origin || !(origin.flags & TypeFlags.Intersection)) { + return; + } + const limitedConstraint = getIntersectionType((origin as IntersectionType).types.filter(t => t !== type.constraintType)); + return limitedConstraint !== neverType ? limitedConstraint : undefined; } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { @@ -13686,23 +13691,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; const members = createSymbolTable(); - const membersLimitingConstraint = getReverseMappedTypeMembersLimitingConstraint(type); + const limitedConstraint = getLimitedConstraint(type); const nameType = getNameTypeFromMappedType(type.mappedType); for (const prop of getPropertiesOfType(type.source)) { - // we skip those properties that are not assignable to either of those "limiters" - // the extra properties wouldn't get through the application of the mapped type anyway - // and their inferred type might not satisfy the type parameter's constraint - // which, in turn, could fail the check if the inferred type is assignable to its constraint - // - // inferring `{ a: number; b: string }` wouldn't satisfy T's constraint so b has to be skipped over here - // - // function fn>({ [K in keyof T & "a"]: T[K] }): T - // const obj = { a: 1, b: '2' }; - // fn(obj); - if (membersLimitingConstraint || nameType) { + // In case of a reverse mapped type with an intersection constraint or a name type + // we skip those properties that are not assignable to them + // because the extra properties wouldn't get through the application of the mapped type anyway + if (limitedConstraint || nameType) { const propertyNameType = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); - if (membersLimitingConstraint && !isTypeAssignableTo(propertyNameType, membersLimitingConstraint)) { + if (limitedConstraint && !isTypeAssignableTo(propertyNameType, limitedConstraint)) { continue; } if (nameType) { @@ -25760,9 +25758,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean { - if (constraintType.flags & TypeFlags.UnionOrIntersection) { + if ((constraintType.flags & TypeFlags.Union) || (constraintType.flags & TypeFlags.Intersection)) { let result = false; - for (const type of (constraintType as UnionOrIntersectionType).types) { + for (const type of (constraintType as (UnionType | IntersectionType)).types) { result = inferToMappedType(source, target, type) || result; } return result; diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt similarity index 62% rename from tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt rename to tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt index a449ffb14b6d4..ec7eab991b0ed 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.errors.txt +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.errors.txt @@ -1,27 +1,32 @@ -reverseMappedTypeLimitedConstraintWithIntersection1.ts(15,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(28,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(39,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(53,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. +reverseMappedTypeIntersectionConstraint.ts(19,7): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +reverseMappedTypeIntersectionConstraint.ts(32,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ entry: "foo"; states: { a: { entry: "foo"; }; }; }'. +reverseMappedTypeIntersectionConstraint.ts(43,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. +reverseMappedTypeIntersectionConstraint.ts(59,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(57,64): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(63,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. +reverseMappedTypeIntersectionConstraint.ts(63,49): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(69,7): error TS2322: Type '{ [K in keyof T & keyof Stuff]: T[K]; }[]' is not assignable to type 'T[]'. Type '{ [K in keyof T & keyof Stuff]: T[K]; }' is not assignable to type 'T'. '{ [K in keyof T & keyof Stuff]: T[K]; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Stuff'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(68,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(81,25): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(92,25): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(94,35): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(107,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(152,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. -reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(74,36): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. +reverseMappedTypeIntersectionConstraint.ts(87,12): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(98,12): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. +reverseMappedTypeIntersectionConstraint.ts(100,22): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. +reverseMappedTypeIntersectionConstraint.ts(113,67): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ prop: "foo"; nested: { prop: string; }; }'. +reverseMappedTypeIntersectionConstraint.ts(152,21): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. +reverseMappedTypeIntersectionConstraint.ts(164,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. +reverseMappedTypeIntersectionConstraint.ts(171,3): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. -==== reverseMappedTypeLimitedConstraintWithIntersection1.ts (13 errors) ==== +==== reverseMappedTypeIntersectionConstraint.ts (14 errors) ==== type StateConfig = { entry?: TAction states?: Record>; }; + type StateSchema = { + states?: Record; + }; + declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, @@ -34,7 +39,7 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj entry: "bar", ~~~~~ !!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. -!!! related TS6500 reverseMappedTypeLimitedConstraintWithIntersection1.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' +!!! related TS6500 reverseMappedTypeIntersectionConstraint.ts:2:3: The expected type comes from property 'entry' which is declared here on type 'StateConfig<"foo">' }, }, extra: 12, @@ -65,6 +70,8 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. }); + checked; + // ----------------------------------------------------------------------------------------- interface Stuff { @@ -83,8 +90,8 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj } } - const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) - ~~~~~ + doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) + ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { @@ -99,7 +106,7 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj } } - const stuff2 = doStuffWithStuffArr([ + doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ field: 1; anotherField: "a"; }'. @@ -109,31 +116,31 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj type XNumber = { x: number } - declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; + declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; function bar(props: {x: number, y: string}) { return foo(props); // no error because lack of excess property check by design } - const foo1 = foo({x: 1, y: 'foo'}); - ~ + foo({x: 1, y: 'foo'}); + ~ !!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. - const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design + foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } - declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; + declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; - const baz1 = baz({x: 1}); - const baz2 = baz({x: 1, z: 123}); - ~ + baz({x: 1}); + baz({x: 1, z: 123}); + ~ !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; }'. - const baz3 = baz({x: 1, y: 'foo'}); - const baz4 = baz({x: 1, y: 'foo', z: 123}); - ~ + baz({x: 1, y: 'foo'}); + baz({x: 1, y: 'foo', z: 123}); + ~ !!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: 1; y: "foo"; }'. // ----------------------------------------------------------------------------------------- @@ -155,6 +162,8 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj type IsLiteralString = string extends T ? false : true; + type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + interface ProvidedActor { src: string; logic: () => Promise; @@ -177,12 +186,18 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj }; } + type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never + } + declare function createXMachine< const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, >(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; const child = () => Promise.resolve("foo"); + ~~~~~~~ +!!! error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later. const config = createXMachine({ types: {} as { @@ -196,7 +211,7 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj }, extra: 10 ~~~~~ -!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => Promise; }; }; invoke: { readonly src: "str"; }; }'. +!!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ types: { actors: { src: "str"; logic: () => any; }; }; invoke: { readonly src: "str"; }; }'. }); const config2 = createXMachine({ @@ -207,23 +222,4 @@ reverseMappedTypeLimitedConstraintWithIntersection1.ts(159,3): error TS2353: Obj ~~~~~ !!! error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ invoke: { readonly src: "whatever"; }; }'. }); - - declare function fn1>(obj: { - [K in keyof T & "a"]: T[K]; - }): T; - const obj1 = { - a: 42, - b: true, - }; - const result1 = fn1(obj1); - - declare function fn2>(obj: { - [K in (keyof T & "a") | "b"]: T[K]; - }): T; - const obj2 = { - a: 42, - b: 100, - c: true, - }; - const result2 = fn2(obj2); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js similarity index 76% rename from tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js rename to tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js index 0d9ba7239290b..a68576c793bf8 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.js +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.js @@ -1,11 +1,15 @@ -//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// -//// [reverseMappedTypeLimitedConstraintWithIntersection1.ts] +//// [reverseMappedTypeIntersectionConstraint.ts] type StateConfig = { entry?: TAction states?: Record>; }; +type StateSchema = { + states?: Record; +}; + declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, @@ -42,6 +46,8 @@ const checked = checkType<{x: number, y: string}>()({ z: "z", // undesirable property z is *not* allowed }); +checked; + // ----------------------------------------------------------------------------------------- interface Stuff { @@ -57,7 +63,7 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } } -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { if(Math.random() > 0.5) { @@ -67,7 +73,7 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } } -const stuff2 = doStuffWithStuffArr([ +doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ]) @@ -75,26 +81,26 @@ const stuff2 = doStuffWithStuffArr([ type XNumber = { x: number } -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; function bar(props: {x: number, y: string}) { return foo(props); // no error because lack of excess property check by design } -const foo1 = foo({x: 1, y: 'foo'}); +foo({x: 1, y: 'foo'}); -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; -const baz1 = baz({x: 1}); -const baz2 = baz({x: 1, z: 123}); -const baz3 = baz({x: 1, y: 'foo'}); -const baz4 = baz({x: 1, y: 'foo', z: 123}); +baz({x: 1}); +baz({x: 1, z: 123}); +baz({x: 1, y: 'foo'}); +baz({x: 1, y: 'foo', z: 123}); // ----------------------------------------------------------------------------------------- @@ -113,6 +119,8 @@ const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); type IsLiteralString = string extends T ? false : true; +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + interface ProvidedActor { src: string; logic: () => Promise; @@ -135,6 +143,10 @@ interface MachineConfig { }; } +type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + declare function createXMachine< const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, @@ -161,28 +173,9 @@ const config2 = createXMachine({ }, extra: 10 }); - -declare function fn1>(obj: { - [K in keyof T & "a"]: T[K]; -}): T; -const obj1 = { - a: 42, - b: true, -}; -const result1 = fn1(obj1); - -declare function fn2>(obj: { - [K in (keyof T & "a") | "b"]: T[K]; -}): T; -const obj2 = { - a: 42, - b: 100, - c: true, -}; -const result2 = fn2(obj2); -//// [reverseMappedTypeLimitedConstraintWithIntersection1.js] +//// [reverseMappedTypeIntersectionConstraint.js] "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { @@ -220,6 +213,7 @@ var checked = checkType()({ y: "y", z: "z", // undesirable property z is *not* allowed }); +checked; function doStuffWithStuff(s) { if (Math.random() > 0.5) { return s; @@ -228,7 +222,7 @@ function doStuffWithStuff(s) { return s; } } -var stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }); function doStuffWithStuffArr(arr) { if (Math.random() > 0.5) { return arr; @@ -237,18 +231,18 @@ function doStuffWithStuffArr(arr) { return arr; } } -var stuff2 = doStuffWithStuffArr([ +doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ]); function bar(props) { return foo(props); // no error because lack of excess property check by design } -var foo1 = foo({ x: 1, y: 'foo' }); -var foo2 = foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design -var baz1 = baz({ x: 1 }); -var baz2 = baz({ x: 1, z: 123 }); -var baz3 = baz({ x: 1, y: 'foo' }); -var baz4 = baz({ x: 1, y: 'foo', z: 123 }); +foo({ x: 1, y: 'foo' }); +foo(__assign({ x: 1, y: 'foo' })); // no error because lack of excess property check by design +baz({ x: 1 }); +baz({ x: 1, z: 123 }); +baz({ x: 1, y: 'foo' }); +baz({ x: 1, y: 'foo', z: 123 }); var wnp = withNestedProp({ prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); var child = function () { return Promise.resolve("foo"); }; var config = createXMachine({ @@ -264,14 +258,3 @@ var config2 = createXMachine({ }, extra: 10 }); -var obj1 = { - a: 42, - b: true, -}; -var result1 = fn1(obj1); -var obj2 = { - a: 42, - b: 100, - c: true, -}; -var result2 = fn2(obj2); diff --git a/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols new file mode 100644 index 0000000000000..12cb8664c8409 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.symbols @@ -0,0 +1,491 @@ +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// + +=== reverseMappedTypeIntersectionConstraint.ts === +type StateConfig = { +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + + entry?: TAction +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 44)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + + states?: Record>; +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 1, 17)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 17)) + +}; + +type StateSchema = { +>StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) + + states?: Record; +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 5, 20)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>StateSchema : Symbol(StateSchema, Decl(reverseMappedTypeIntersectionConstraint.ts, 3, 2)) + +}; + +declare function createMachine< +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + TConfig extends StateConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) + + TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) + +>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 0, 0)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 12, 13)) +>TAction : Symbol(TAction, Decl(reverseMappedTypeIntersectionConstraint.ts, 10, 39)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 9, 31)) + +const inferredParams1 = createMachine({ +>inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 14, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 15, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 16, 11)) + + entry: "bar", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 17, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 20, 4)) + +}); + +const inferredParams2 = createMachine({ +>inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 5)) +>createMachine : Symbol(createMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 7, 2)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 24, 39)) + + states: { +>states : Symbol(states, Decl(reverseMappedTypeIntersectionConstraint.ts, 25, 15)) + + a: { +>a : Symbol(a, Decl(reverseMappedTypeIntersectionConstraint.ts, 26, 11)) + + entry: "foo", +>entry : Symbol(entry, Decl(reverseMappedTypeIntersectionConstraint.ts, 27, 8)) + + }, + }, + extra: 12, +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 30, 4)) + +}); + + +// ----------------------------------------------------------------------------------------- + +const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 19)) +>U : Symbol(U, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 28)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 51)) +>value : Symbol(value, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 41)) + +const checked = checkType<{x: number, y: string}>()({ +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) +>checkType : Symbol(checkType, Decl(reverseMappedTypeIntersectionConstraint.ts, 37, 5)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 27)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 37)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 53)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 40, 17)) + + z: "z", // undesirable property z is *not* allowed +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 41, 9)) + +}); + +checked; +>checked : Symbol(checked, Decl(reverseMappedTypeIntersectionConstraint.ts, 39, 5)) + +// ----------------------------------------------------------------------------------------- + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) + + field: number; +>field : Symbol(Stuff.field, Decl(reverseMappedTypeIntersectionConstraint.ts, 49, 17)) + + anotherField: string; +>anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 50, 18)) +} + +function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return s as T +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 26)) + + } else { + return s +>s : Symbol(s, Decl(reverseMappedTypeIntersectionConstraint.ts, 54, 43)) + } +} + +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +>doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 52, 1)) +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 18)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 28)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 47)) + +function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>Stuff : Symbol(Stuff, Decl(reverseMappedTypeIntersectionConstraint.ts, 45, 8)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 54)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) + + if(Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return arr as T[] +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 29)) + + } else { + return arr +>arr : Symbol(arr, Decl(reverseMappedTypeIntersectionConstraint.ts, 64, 46)) + } +} + +doStuffWithStuffArr([ +>doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeIntersectionConstraint.ts, 62, 61)) + + { field: 1, anotherField: 'a', extra: 123 }, +>field : Symbol(field, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 5)) +>anotherField : Symbol(anotherField, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 15)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 73, 34)) + +]) + +// ----------------------------------------------------------------------------------------- + +type XNumber = { x: number } +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 16)) + +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 40)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>XNumber : Symbol(XNumber, Decl(reverseMappedTypeIntersectionConstraint.ts, 74, 2)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 49)) + +function bar(props: {x: number, y: string}) { +>bar : Symbol(bar, Decl(reverseMappedTypeIntersectionConstraint.ts, 80, 93)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 21)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 31)) + + return foo(props); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 82, 13)) +} + +foo({x: 1, y: 'foo'}); +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 86, 10)) + +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo : Symbol(foo, Decl(reverseMappedTypeIntersectionConstraint.ts, 78, 28)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 9)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 14)) + +// ----------------------------------------------------------------------------------------- + +type NoErrWithOptProps = { x: number, y?: string } +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 26)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 37)) + +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 50)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeIntersectionConstraint.ts, 88, 27)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 21)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 94, 59)) + +baz({x: 1}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 96, 5)) + +baz({x: 1, z: 123}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 5)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 97, 10)) + +baz({x: 1, y: 'foo'}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 98, 10)) + +baz({x: 1, y: 'foo', z: 123}); +>baz : Symbol(baz, Decl(reverseMappedTypeIntersectionConstraint.ts, 92, 50)) +>x : Symbol(x, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 5)) +>y : Symbol(y, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 10)) +>z : Symbol(z, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 20)) + +// ----------------------------------------------------------------------------------------- + +interface WithNestedProp { +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) + + prop: string; +>prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 103, 26)) + + nested: { +>nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 104, 15)) + + prop: string; +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 105, 11)) + } +} + +declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>props : Symbol(props, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 58)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 99, 30)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 67)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 110, 32)) + +const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); +>wnp : Symbol(wnp, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 5)) +>withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeIntersectionConstraint.ts, 108, 1)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 28)) +>nested : Symbol(nested, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 40)) +>prop : Symbol(prop, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 50)) +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 65)) + +// ----------------------------------------------------------------------------------------- + +type IsLiteralString = string extends T ? false : true; +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 21)) + +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>DeepWritable : Symbol(DeepWritable, Decl(reverseMappedTypeIntersectionConstraint.ts, 116, 73)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 18)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 61)) + +interface ProvidedActor { +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) + + src: string; +>src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeIntersectionConstraint.ts, 120, 25)) + + logic: () => Promise; +>logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 121, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +} + +type DistributeActors = TActor extends { src: infer TSrc } +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 22)) +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 48)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) + + ? { + src: TSrc; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 126, 5)) +>TSrc : Symbol(TSrc, Decl(reverseMappedTypeIntersectionConstraint.ts, 125, 59)) + } + : never; + +interface MachineConfig { +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) + + types?: { +>types : Symbol(MachineConfig.types, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 55)) + + actors?: TActor; +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 132, 11)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) + + }; + invoke: IsLiteralString extends true +>invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 134, 4)) +>IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeIntersectionConstraint.ts, 112, 79)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) + + ? DistributeActors +>DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeIntersectionConstraint.ts, 123, 1)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 131, 24)) + + : { + src: string; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 137, 7)) + + }; +} + +type NoExtra = { +>NoExtra : Symbol(NoExtra, Decl(reverseMappedTypeIntersectionConstraint.ts, 140, 1)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) + + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>T : Symbol(T, Decl(reverseMappedTypeIntersectionConstraint.ts, 142, 13)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 143, 3)) +} + +declare function createXMachine< +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) + + const TConfig extends MachineConfig, +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) + + TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, +>TActor : Symbol(TActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 147, 46)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 50)) +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 148, 59)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeIntersectionConstraint.ts, 118, 96)) + +>(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 2)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) +>MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 129, 10)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) +>K : Symbol(K, Decl(reverseMappedTypeIntersectionConstraint.ts, 149, 12)) +>TConfig : Symbol(TConfig, Decl(reverseMappedTypeIntersectionConstraint.ts, 146, 32)) + +const child = () => Promise.resolve("foo"); +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) + +const config = createXMachine({ +>config : Symbol(config, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) + + types: {} as { +>types : Symbol(types, Decl(reverseMappedTypeIntersectionConstraint.ts, 153, 31)) + + actors: { +>actors : Symbol(actors, Decl(reverseMappedTypeIntersectionConstraint.ts, 154, 16)) + + src: "str"; +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 155, 13)) + + logic: typeof child; +>logic : Symbol(logic, Decl(reverseMappedTypeIntersectionConstraint.ts, 156, 17)) +>child : Symbol(child, Decl(reverseMappedTypeIntersectionConstraint.ts, 151, 5)) + + }; + }, + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 159, 4)) + + src: "str", +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 160, 11)) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 162, 4)) + +}); + +const config2 = createXMachine({ +>config2 : Symbol(config2, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 5)) +>createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeIntersectionConstraint.ts, 144, 1)) + + invoke: { +>invoke : Symbol(invoke, Decl(reverseMappedTypeIntersectionConstraint.ts, 166, 32)) + + src: "whatever", +>src : Symbol(src, Decl(reverseMappedTypeIntersectionConstraint.ts, 167, 11)) + + }, + extra: 10 +>extra : Symbol(extra, Decl(reverseMappedTypeIntersectionConstraint.ts, 169, 4)) + +}); + diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types similarity index 78% rename from tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types rename to tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types index e5bba36010ccd..43b568dd83d87 100644 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.types +++ b/tests/baselines/reference/reverseMappedTypeIntersectionConstraint.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// +//// [tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts] //// -=== reverseMappedTypeLimitedConstraintWithIntersection1.ts === +=== reverseMappedTypeIntersectionConstraint.ts === type StateConfig = { >StateConfig : StateConfig @@ -12,6 +12,14 @@ type StateConfig = { }; +type StateSchema = { +>StateSchema : { states?: Record | undefined; } + + states?: Record; +>states : Record | undefined + +}; + declare function createMachine< >createMachine : , TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string>(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K]; }) => [TAction, TConfig] @@ -114,6 +122,9 @@ const checked = checkType<{x: number, y: string}>()({ }); +checked; +>checked : { x: number; y: "y"; } + // ----------------------------------------------------------------------------------------- interface Stuff { @@ -146,8 +157,7 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } } -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->stuff1 : { field: 1; anotherField: "a"; } +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) >doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) : { field: 1; anotherField: "a"; } >doStuffWithStuff : (s: { [K in keyof T & keyof Stuff]: T[K]; }) => T >{ field: 1, anotherField: 'a', extra: 123 } : { field: 1; anotherField: "a"; extra: number; } @@ -180,8 +190,7 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } } -const stuff2 = doStuffWithStuffArr([ ->stuff2 : { field: 1; anotherField: "a"; }[] +doStuffWithStuffArr([ >doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 },]) : { field: 1; anotherField: "a"; }[] >doStuffWithStuffArr : (arr: { [K in keyof T & keyof Stuff]: T[K]; }[]) => T[] >[ { field: 1, anotherField: 'a', extra: 123 },] : { field: 1; anotherField: "a"; extra: number; }[] @@ -203,36 +212,34 @@ type XNumber = { x: number } >XNumber : { x: number; } >x : number -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void >props : { [K in keyof T & "x"]: T[K]; } function bar(props: {x: number, y: string}) { ->bar : (props: { x: number; y: string;}) => { x: number; } +>bar : (props: { x: number; y: string;}) => void >props : { x: number; y: string; } >x : number >y : string return foo(props); // no error because lack of excess property check by design ->foo(props) : { x: number; } ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +>foo(props) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void >props : { x: number; y: string; } } -const foo1 = foo({x: 1, y: 'foo'}); ->foo1 : { x: 1; } ->foo({x: 1, y: 'foo'}) : { x: 1; } ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +foo({x: 1, y: 'foo'}); +>foo({x: 1, y: 'foo'}) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void >{x: 1, y: 'foo'} : { x: 1; y: string; } >x : 1 >1 : 1 >y : string >'foo' : "foo" -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo2 : { x: 1; } ->foo({...{x: 1, y: 'foo'}}) : { x: 1; } ->foo : (props: { [K in keyof T & "x"]: T[K]; }) => T +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +>foo({...{x: 1, y: 'foo'}}) : void +>foo : (props: { [K in keyof T & "x"]: T[K]; }) => void >{...{x: 1, y: 'foo'}} : { x: 1; y: string; } >{x: 1, y: 'foo'} : { x: 1; y: string; } >x : 1 @@ -247,42 +254,38 @@ type NoErrWithOptProps = { x: number, y?: string } >x : number >y : string | undefined -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void >props : { [K in keyof T & keyof NoErrWithOptProps]: T[K]; } -const baz1 = baz({x: 1}); ->baz1 : { x: 1; } ->baz({x: 1}) : { x: 1; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +baz({x: 1}); +>baz({x: 1}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void >{x: 1} : { x: 1; } >x : 1 >1 : 1 -const baz2 = baz({x: 1, z: 123}); ->baz2 : { x: 1; } ->baz({x: 1, z: 123}) : { x: 1; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +baz({x: 1, z: 123}); +>baz({x: 1, z: 123}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void >{x: 1, z: 123} : { x: 1; z: number; } >x : 1 >1 : 1 >z : number >123 : 123 -const baz3 = baz({x: 1, y: 'foo'}); ->baz3 : { x: 1; y: "foo"; } ->baz({x: 1, y: 'foo'}) : { x: 1; y: "foo"; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +baz({x: 1, y: 'foo'}); +>baz({x: 1, y: 'foo'}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void >{x: 1, y: 'foo'} : { x: 1; y: "foo"; } >x : 1 >1 : 1 >y : "foo" >'foo' : "foo" -const baz4 = baz({x: 1, y: 'foo', z: 123}); ->baz4 : { x: 1; y: "foo"; } ->baz({x: 1, y: 'foo', z: 123}) : { x: 1; y: "foo"; } ->baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => T +baz({x: 1, y: 'foo', z: 123}); +>baz({x: 1, y: 'foo', z: 123}) : void +>baz : (props: { [K in keyof T & keyof NoErrWithOptProps]: T[K]; }) => void >{x: 1, y: 'foo', z: 123} : { x: 1; y: "foo"; z: number; } >x : 1 >1 : 1 @@ -330,6 +333,9 @@ type IsLiteralString = string extends T ? false : true; >false : false >true : true +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } +>DeepWritable : DeepWritable + interface ProvidedActor { src: string; >src : string @@ -368,6 +374,12 @@ interface MachineConfig { }; } +type NoExtra = { +>NoExtra : NoExtra + + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + declare function createXMachine< >createXMachine : , TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor;}; } ? TConfig["types"]["actors"] : ProvidedActor>(config: { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; }) => TConfig @@ -380,12 +392,12 @@ declare function createXMachine< >config : { [K in keyof MachineConfig & keyof TConfig]: TConfig[K]; } const child = () => Promise.resolve("foo"); ->child : () => Promise ->() => Promise.resolve("foo") : () => Promise ->Promise.resolve("foo") : Promise ->Promise.resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } ->Promise : PromiseConstructor ->resolve : { (): Promise; (value: T): Promise>; (value: T_1 | PromiseLike): Promise>; } +>child : () => any +>() => Promise.resolve("foo") : () => any +>Promise.resolve("foo") : any +>Promise.resolve : any +>Promise : any +>resolve : any >"foo" : "foo" const config = createXMachine({ @@ -406,8 +418,8 @@ const config = createXMachine({ >src : "str" logic: typeof child; ->logic : () => Promise ->child : () => Promise +>logic : () => any +>child : () => any }; }, @@ -447,57 +459,3 @@ const config2 = createXMachine({ }); -declare function fn1>(obj: { ->fn1 : >(obj: { [K in keyof T & "a"]: T[K]; }) => T ->obj : { [K in keyof T & "a"]: T[K]; } - - [K in keyof T & "a"]: T[K]; -}): T; -const obj1 = { ->obj1 : { a: number; b: boolean; } ->{ a: 42, b: true,} : { a: number; b: boolean; } - - a: 42, ->a : number ->42 : 42 - - b: true, ->b : boolean ->true : true - -}; -const result1 = fn1(obj1); ->result1 : { a: number; } ->fn1(obj1) : { a: number; } ->fn1 : >(obj: { [K in keyof T & "a"]: T[K]; }) => T ->obj1 : { a: number; b: boolean; } - -declare function fn2>(obj: { ->fn2 : >(obj: { [K in "b" | (keyof T & "a")]: T[K]; }) => T ->obj : { [K in "b" | (keyof T & "a")]: T[K]; } - - [K in (keyof T & "a") | "b"]: T[K]; -}): T; -const obj2 = { ->obj2 : { a: number; b: number; c: boolean; } ->{ a: 42, b: 100, c: true,} : { a: number; b: number; c: boolean; } - - a: 42, ->a : number ->42 : 42 - - b: 100, ->b : number ->100 : 100 - - c: true, ->c : boolean ->true : true - -}; -const result2 = fn2(obj2); ->result2 : { a: number; b: number; } ->fn2(obj2) : { a: number; b: number; } ->fn2 : >(obj: { [K in "b" | (keyof T & "a")]: T[K]; }) => T ->obj2 : { a: number; b: number; c: boolean; } - diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt new file mode 100644 index 0000000000000..dc6dc8fa3a331 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.errors.txt @@ -0,0 +1,24 @@ +reverseMappedTypeLimitedConstraint.ts(5,13): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. +reverseMappedTypeLimitedConstraint.ts(14,3): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + + +==== reverseMappedTypeLimitedConstraint.ts (2 errors) ==== + type XNumber_ = { x: number } + + declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + + foo_({x: 1, y: 'foo'}); + ~ +!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: 1; }'. + + // ----------------------------------------------------------------------------------------- + + const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + + const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", + ~ +!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: "y"; }'. + }); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js new file mode 100644 index 0000000000000..0be7aa8d6a423 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +//// [reverseMappedTypeLimitedConstraint.ts] +type XNumber_ = { x: number } + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + +foo_({x: 1, y: 'foo'}); + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", +}); + +//// [reverseMappedTypeLimitedConstraint.js] +foo_({ x: 1, y: 'foo' }); +// ----------------------------------------------------------------------------------------- +var checkType_ = function () { return function (value) { return value; }; }; +var checked_ = checkType_()({ + x: 1, + y: "y", + z: "z", +}); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols new file mode 100644 index 0000000000000..5c81507278445 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.symbols @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +=== reverseMappedTypeLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 17)) + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>props : Symbol(props, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>XNumber_ : Symbol(XNumber_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 51)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 2, 22)) + +foo_({x: 1, y: 'foo'}); +>foo_ : Symbol(foo_, Decl(reverseMappedTypeLimitedConstraint.ts, 0, 29)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 6)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 4, 11)) + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>T : Symbol(T, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 20)) +>U : Symbol(U, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 29)) +>K : Symbol(K, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 52)) +>value : Symbol(value, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 42)) + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : Symbol(checked_, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 5)) +>checkType_ : Symbol(checkType_, Decl(reverseMappedTypeLimitedConstraint.ts, 8, 5)) +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 29)) +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 39)) + + x: 1 as number, +>x : Symbol(x, Decl(reverseMappedTypeLimitedConstraint.ts, 10, 55)) + + y: "y", +>y : Symbol(y, Decl(reverseMappedTypeLimitedConstraint.ts, 11, 17)) + + z: "z", +>z : Symbol(z, Decl(reverseMappedTypeLimitedConstraint.ts, 12, 9)) + +}); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types new file mode 100644 index 0000000000000..821d7685fcccd --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeLimitedConstraint.types @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts] //// + +=== reverseMappedTypeLimitedConstraint.ts === +type XNumber_ = { x: number } +>XNumber_ : { x: number; } +>x : number + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; +>foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T +>props : { [K in keyof T & "x"]: T[K]; } + +foo_({x: 1, y: 'foo'}); +>foo_({x: 1, y: 'foo'}) : { x: 1; } +>foo_ : (props: { [K in keyof T & "x"]: T[K]; }) => T +>{x: 1, y: 'foo'} : { x: 1; y: string; } +>x : 1 +>1 : 1 +>y : string +>'foo' : "foo" + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; +>checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>() => (value: { [K in keyof U & keyof T]: U[K] }) => value : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>(value: { [K in keyof U & keyof T]: U[K] }) => value : (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } +>value : { [K in keyof U & keyof T]: U[K]; } + +const checked_ = checkType_<{x: number, y: string}>()({ +>checked_ : { x: number; y: "y"; } +>checkType_<{x: number, y: string}>()({ x: 1 as number, y: "y", z: "z",}) : { x: number; y: "y"; } +>checkType_<{x: number, y: string}>() : (value: { [K in keyof U & ("x" | "y")]: U[K]; }) => { [K in keyof U & ("x" | "y")]: U[K]; } +>checkType_ : () => (value: { [K in keyof U & keyof T]: U[K]; }) => { [K in keyof U & keyof T]: U[K]; } +>x : number +>y : string +>{ x: 1 as number, y: "y", z: "z",} : { x: number; y: "y"; z: string; } + + x: 1 as number, +>x : number +>1 as number : number +>1 : 1 + + y: "y", +>y : "y" +>"y" : "y" + + z: "z", +>z : string +>"z" : "z" + +}); diff --git a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols b/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols deleted file mode 100644 index 762f94ecc7e31..0000000000000 --- a/tests/baselines/reference/reverseMappedTypeLimitedConstraintWithIntersection1.symbols +++ /dev/null @@ -1,529 +0,0 @@ -//// [tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts] //// - -=== reverseMappedTypeLimitedConstraintWithIntersection1.ts === -type StateConfig = { ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) - - entry?: TAction ->entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 44)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) - - states?: Record>; ->states : Symbol(states, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 1, 17)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 17)) - -}; - -declare function createMachine< ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 3, 2)) - - TConfig extends StateConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 6, 39)) - - TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, ->TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 6, 39)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) - ->(config: { [K in keyof TConfig & keyof StateConfig]: TConfig[K] }): [TAction, TConfig]; ->config : Symbol(config, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 2)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 13)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) ->StateConfig : Symbol(StateConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 0, 0)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 8, 13)) ->TAction : Symbol(TAction, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 6, 39)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 5, 31)) - -const inferredParams1 = createMachine({ ->inferredParams1 : Symbol(inferredParams1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 5)) ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 3, 2)) - - entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 10, 39)) - - states: { ->states : Symbol(states, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 11, 15)) - - a: { ->a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 12, 11)) - - entry: "bar", ->entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 13, 8)) - - }, - }, - extra: 12, ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 16, 4)) - -}); - -const inferredParams2 = createMachine({ ->inferredParams2 : Symbol(inferredParams2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 20, 5)) ->createMachine : Symbol(createMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 3, 2)) - - entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 20, 39)) - - states: { ->states : Symbol(states, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 21, 15)) - - a: { ->a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 22, 11)) - - entry: "foo", ->entry : Symbol(entry, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 23, 8)) - - }, - }, - extra: 12, ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 26, 4)) - -}); - - -// ----------------------------------------------------------------------------------------- - -const checkType = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; ->checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 5)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 19)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 28)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 19)) ->value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 41)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 51)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 28)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 19)) ->U : Symbol(U, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 28)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 51)) ->value : Symbol(value, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 41)) - -const checked = checkType<{x: number, y: string}>()({ ->checked : Symbol(checked, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 5)) ->checkType : Symbol(checkType, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 33, 5)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 27)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 37)) - - x: 1 as number, ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 35, 53)) - - y: "y", ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 36, 17)) - - z: "z", // undesirable property z is *not* allowed ->z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 37, 9)) - -}); - -// ----------------------------------------------------------------------------------------- - -interface Stuff { ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) - - field: number; ->field : Symbol(Stuff.field, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 43, 17)) - - anotherField: string; ->anotherField : Symbol(Stuff.anotherField, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 44, 18)) -} - -function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[K] } ): T { ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 46, 1)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) ->s : Symbol(s, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 43)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 49)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 49)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) - - if(Math.random() > 0.5) { ->Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - - return s as T ->s : Symbol(s, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 43)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 26)) - - } else { - return s ->s : Symbol(s, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 48, 43)) - } -} - -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) ->stuff1 : Symbol(stuff1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 5)) ->doStuffWithStuff : Symbol(doStuffWithStuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 46, 1)) ->field : Symbol(field, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 33)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 43)) ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 62)) - -function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 76)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) ->arr : Symbol(arr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 46)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 54)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) ->Stuff : Symbol(Stuff, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 39, 3)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 54)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) - - if(Math.random() > 0.5) { ->Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) ->Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) - - return arr as T[] ->arr : Symbol(arr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 46)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 29)) - - } else { - return arr ->arr : Symbol(arr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 58, 46)) - } -} - -const stuff2 = doStuffWithStuffArr([ ->stuff2 : Symbol(stuff2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 66, 5)) ->doStuffWithStuffArr : Symbol(doStuffWithStuffArr, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 56, 76)) - - { field: 1, anotherField: 'a', extra: 123 }, ->field : Symbol(field, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 67, 5)) ->anotherField : Symbol(anotherField, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 67, 15)) ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 67, 34)) - -]) - -// ----------------------------------------------------------------------------------------- - -type XNumber = { x: number } ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 68, 2)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 16)) - -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; ->foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 68, 2)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 40)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 49)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) ->XNumber : Symbol(XNumber, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 68, 2)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 49)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 21)) - -function bar(props: {x: number, y: string}) { ->bar : Symbol(bar, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 74, 90)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 13)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 21)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 31)) - - return foo(props); // no error because lack of excess property check by design ->foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 76, 13)) -} - -const foo1 = foo({x: 1, y: 'foo'}); ->foo1 : Symbol(foo1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 80, 5)) ->foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 80, 18)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 80, 23)) - -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design ->foo2 : Symbol(foo2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 5)) ->foo : Symbol(foo, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 72, 28)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 22)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 27)) - -// ----------------------------------------------------------------------------------------- - -type NoErrWithOptProps = { x: number, y?: string } ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 40)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 26)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 37)) - -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; ->baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 40)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 50)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 59)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) ->NoErrWithOptProps : Symbol(NoErrWithOptProps, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 82, 40)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 59)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 88, 21)) - -const baz1 = baz({x: 1}); ->baz1 : Symbol(baz1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 90, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 90, 18)) - -const baz2 = baz({x: 1, z: 123}); ->baz2 : Symbol(baz2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 91, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 91, 18)) ->z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 91, 23)) - -const baz3 = baz({x: 1, y: 'foo'}); ->baz3 : Symbol(baz3, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 92, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 92, 18)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 92, 23)) - -const baz4 = baz({x: 1, y: 'foo', z: 123}); ->baz4 : Symbol(baz4, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 5)) ->baz : Symbol(baz, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 86, 50)) ->x : Symbol(x, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 18)) ->y : Symbol(y, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 23)) ->z : Symbol(z, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 33)) - -// ----------------------------------------------------------------------------------------- - -interface WithNestedProp { ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 43)) - - prop: string; ->prop : Symbol(WithNestedProp.prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 97, 26)) - - nested: { ->nested : Symbol(WithNestedProp.nested, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 98, 15)) - - prop: string; ->prop : Symbol(prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 99, 11)) - } -} - -declare function withNestedProp(props: {[K in keyof T & keyof WithNestedProp]: T[K]}): T; ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 102, 1)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 43)) ->props : Symbol(props, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 58)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 67)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) ->WithNestedProp : Symbol(WithNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 93, 43)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 67)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 104, 32)) - -const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); ->wnp : Symbol(wnp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 5)) ->withNestedProp : Symbol(withNestedProp, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 102, 1)) ->prop : Symbol(prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 28)) ->nested : Symbol(nested, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 40)) ->prop : Symbol(prop, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 50)) ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 65)) - -// ----------------------------------------------------------------------------------------- - -type IsLiteralString = string extends T ? false : true; ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 79)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 21)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 21)) - -interface ProvidedActor { ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) - - src: string; ->src : Symbol(ProvidedActor.src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 112, 25)) - - logic: () => Promise; ->logic : Symbol(ProvidedActor.logic, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 113, 14)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) -} - -type DistributeActors = TActor extends { src: infer TSrc } ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 115, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 22)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 22)) ->src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 48)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 59)) - - ? { - src: TSrc; ->src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 118, 5)) ->TSrc : Symbol(TSrc, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 117, 59)) - } - : never; - -interface MachineConfig { ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 121, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) - - types?: { ->types : Symbol(MachineConfig.types, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 55)) - - actors?: TActor; ->actors : Symbol(actors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 124, 11)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) - - }; - invoke: IsLiteralString extends true ->invoke : Symbol(MachineConfig.invoke, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 126, 4)) ->IsLiteralString : Symbol(IsLiteralString, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 106, 79)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) - - ? DistributeActors ->DistributeActors : Symbol(DistributeActors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 115, 1)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 123, 24)) - - : { - src: string; ->src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 129, 7)) - - }; -} - -declare function createXMachine< ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 132, 1)) - - const TConfig extends MachineConfig, ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 121, 10)) ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 135, 46)) - - TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, ->TActor : Symbol(TActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 135, 46)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) ->types : Symbol(types, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 136, 50)) ->actors : Symbol(actors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 136, 59)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) ->ProvidedActor : Symbol(ProvidedActor, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 110, 73)) - ->(config: {[K in keyof MachineConfig & keyof TConfig]: TConfig[K] }): TConfig; ->config : Symbol(config, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 137, 2)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 137, 12)) ->MachineConfig : Symbol(MachineConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 121, 10)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 137, 12)) ->TConfig : Symbol(TConfig, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 134, 32)) - -const child = () => Promise.resolve("foo"); ->child : Symbol(child, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 139, 5)) ->Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) ->resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) - -const config = createXMachine({ ->config : Symbol(config, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 141, 5)) ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 132, 1)) - - types: {} as { ->types : Symbol(types, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 141, 31)) - - actors: { ->actors : Symbol(actors, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 142, 16)) - - src: "str"; ->src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 143, 13)) - - logic: typeof child; ->logic : Symbol(logic, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 144, 17)) ->child : Symbol(child, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 139, 5)) - - }; - }, - invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 147, 4)) - - src: "str", ->src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 148, 11)) - - }, - extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 150, 4)) - -}); - -const config2 = createXMachine({ ->config2 : Symbol(config2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 154, 5)) ->createXMachine : Symbol(createXMachine, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 132, 1)) - - invoke: { ->invoke : Symbol(invoke, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 154, 32)) - - src: "whatever", ->src : Symbol(src, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 155, 11)) - - }, - extra: 10 ->extra : Symbol(extra, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 157, 4)) - -}); - -declare function fn1>(obj: { ->fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 159, 3)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 55)) - - [K in keyof T & "a"]: T[K]; ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 162, 3)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 162, 3)) - -}): T; ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 161, 21)) - -const obj1 = { ->obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 5)) - - a: 42, ->a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 14)) - - b: true, ->b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 165, 8)) - -}; -const result1 = fn1(obj1); ->result1 : Symbol(result1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 168, 5)) ->fn1 : Symbol(fn1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 159, 3)) ->obj1 : Symbol(obj1, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 164, 5)) - -declare function fn2>(obj: { ->fn2 : Symbol(fn2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 168, 26)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->obj : Symbol(obj, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 55)) - - [K in (keyof T & "a") | "b"]: T[K]; ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 171, 3)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) ->K : Symbol(K, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 171, 3)) - -}): T; ->T : Symbol(T, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 170, 21)) - -const obj2 = { ->obj2 : Symbol(obj2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 173, 5)) - - a: 42, ->a : Symbol(a, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 173, 14)) - - b: 100, ->b : Symbol(b, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 174, 8)) - - c: true, ->c : Symbol(c, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 175, 9)) - -}; -const result2 = fn2(obj2); ->result2 : Symbol(result2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 178, 5)) ->fn2 : Symbol(fn2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 168, 26)) ->obj2 : Symbol(obj2, Decl(reverseMappedTypeLimitedConstraintWithIntersection1.ts, 173, 5)) - diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts similarity index 81% rename from tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts rename to tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts index 6d1f88562f55d..e565549791177 100644 --- a/tests/cases/compiler/reverseMappedTypeLimitedConstraintWithIntersection1.ts +++ b/tests/cases/compiler/reverseMappedTypeIntersectionConstraint.ts @@ -1,11 +1,14 @@ // @strict: true -// @lib: esnext type StateConfig = { entry?: TAction states?: Record>; }; +type StateSchema = { + states?: Record; +}; + declare function createMachine< TConfig extends StateConfig, TAction extends string = TConfig["entry"] extends string ? TConfig["entry"] : string, @@ -42,6 +45,8 @@ const checked = checkType<{x: number, y: string}>()({ z: "z", // undesirable property z is *not* allowed }); +checked; + // ----------------------------------------------------------------------------------------- interface Stuff { @@ -57,7 +62,7 @@ function doStuffWithStuff(s: { [K in keyof T & keyof Stuff]: T[ } } -const stuff1 = doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) +doStuffWithStuff({ field: 1, anotherField: 'a', extra: 123 }) function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff]: T[K] }[]): T[] { if(Math.random() > 0.5) { @@ -67,7 +72,7 @@ function doStuffWithStuffArr(arr: { [K in keyof T & keyof Stuff } } -const stuff2 = doStuffWithStuffArr([ +doStuffWithStuffArr([ { field: 1, anotherField: 'a', extra: 123 }, ]) @@ -75,26 +80,26 @@ const stuff2 = doStuffWithStuffArr([ type XNumber = { x: number } -declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): T; +declare function foo(props: {[K in keyof T & keyof XNumber]: T[K]}): void; function bar(props: {x: number, y: string}) { return foo(props); // no error because lack of excess property check by design } -const foo1 = foo({x: 1, y: 'foo'}); +foo({x: 1, y: 'foo'}); -const foo2 = foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design +foo({...{x: 1, y: 'foo'}}); // no error because lack of excess property check by design // ----------------------------------------------------------------------------------------- type NoErrWithOptProps = { x: number, y?: string } -declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): T; +declare function baz(props: {[K in keyof T & keyof NoErrWithOptProps]: T[K]}): void; -const baz1 = baz({x: 1}); -const baz2 = baz({x: 1, z: 123}); -const baz3 = baz({x: 1, y: 'foo'}); -const baz4 = baz({x: 1, y: 'foo', z: 123}); +baz({x: 1}); +baz({x: 1, z: 123}); +baz({x: 1, y: 'foo'}); +baz({x: 1, y: 'foo', z: 123}); // ----------------------------------------------------------------------------------------- @@ -113,6 +118,8 @@ const wnp = withNestedProp({prop: 'foo', nested: { prop: 'bar' }, extra: 10 }); type IsLiteralString = string extends T ? false : true; +type DeepWritable = T extends Function ? T : { -readonly [K in keyof T]: DeepWritable } + interface ProvidedActor { src: string; logic: () => Promise; @@ -135,6 +142,10 @@ interface MachineConfig { }; } +type NoExtra = { + [K in keyof T]: K extends keyof MachineConfig ? T[K] : never +} + declare function createXMachine< const TConfig extends MachineConfig, TActor extends ProvidedActor = TConfig extends { types: { actors: ProvidedActor} } ? TConfig["types"]["actors"] : ProvidedActor, @@ -161,22 +172,3 @@ const config2 = createXMachine({ }, extra: 10 }); - -declare function fn1>(obj: { - [K in keyof T & "a"]: T[K]; -}): T; -const obj1 = { - a: 42, - b: true, -}; -const result1 = fn1(obj1); - -declare function fn2>(obj: { - [K in (keyof T & "a") | "b"]: T[K]; -}): T; -const obj2 = { - a: 42, - b: 100, - c: true, -}; -const result2 = fn2(obj2); diff --git a/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts b/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts new file mode 100644 index 0000000000000..7618ae65046a9 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeLimitedConstraint.ts @@ -0,0 +1,15 @@ +type XNumber_ = { x: number } + +declare function foo_(props: {[K in keyof T & keyof XNumber_]: T[K]}): T; + +foo_({x: 1, y: 'foo'}); + +// ----------------------------------------------------------------------------------------- + +const checkType_ = () => (value: { [K in keyof U & keyof T]: U[K] }) => value; + +const checked_ = checkType_<{x: number, y: string}>()({ + x: 1 as number, + y: "y", + z: "z", +}); \ No newline at end of file