diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 9dac7a0507b..87110af30a3 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -26200,46 +26200,11 @@ func (c *Checker) getSubstitutionIntersection(t *Type) *Type { func (c *Checker) shouldDeferIndexType(t *Type, indexFlags IndexFlags) bool { return t.flags&TypeFlagsInstantiableNonPrimitive != 0 || c.isGenericTupleType(t) || - c.isGenericMappedType(t) && (!c.hasDistributiveNameType(t) || c.getMappedTypeNameTypeKind(t) == MappedTypeNameTypeKindRemapping) || + c.isGenericMappedType(t) && c.getNameTypeFromMappedType(t) != nil || t.flags&TypeFlagsUnion != 0 && indexFlags&IndexFlagsNoReducibleCheck == 0 && c.isGenericReducibleType(t) || t.flags&TypeFlagsIntersection != 0 && c.maybeTypeOfKind(t, TypeFlagsInstantiable) && core.Some(t.Types(), c.IsEmptyAnonymousObjectType) } -// Ordinarily we reduce a keyof M, where M is a mapped type { [P in K as N

]: X }, to simply N. This however presumes -// that N distributes over union types, i.e. that N is equivalent to N | N | N. Specifically, we only -// want to perform the reduction when the name type of a mapped type is distributive with respect to the type variable -// introduced by the 'in' clause of the mapped type. Note that non-generic types are considered to be distributive because -// they're the same type regardless of what's being distributed over. -func (c *Checker) hasDistributiveNameType(mappedType *Type) bool { - typeVariable := c.getTypeParameterFromMappedType(mappedType) - var isDistributive func(*Type) bool - isDistributive = func(t *Type) bool { - switch { - case t.flags&(TypeFlagsAnyOrUnknown|TypeFlagsPrimitive|TypeFlagsNever|TypeFlagsTypeParameter|TypeFlagsObject|TypeFlagsNonPrimitive) != 0: - return true - case t.flags&TypeFlagsConditional != 0: - return t.AsConditionalType().root.isDistributive && t.AsConditionalType().checkType == typeVariable - case t.flags&TypeFlagsUnionOrIntersection != 0: - return core.Every(t.Types(), isDistributive) - case t.flags&TypeFlagsTemplateLiteral != 0: - return core.Every(t.AsTemplateLiteralType().types, isDistributive) - case t.flags&TypeFlagsIndexedAccess != 0: - return isDistributive(t.AsIndexedAccessType().objectType) && isDistributive(t.AsIndexedAccessType().indexType) - case t.flags&TypeFlagsSubstitution != 0: - return isDistributive(t.AsSubstitutionType().baseType) && isDistributive(t.AsSubstitutionType().constraint) - case t.flags&TypeFlagsStringMapping != 0: - return isDistributive(t.Target()) - default: - return false - } - } - nameType := c.getNameTypeFromMappedType(mappedType) - if nameType == nil { - nameType = typeVariable - } - return isDistributive(nameType) -} - func (c *Checker) getMappedTypeNameTypeKind(t *Type) MappedTypeNameTypeKind { nameType := c.getNameTypeFromMappedType(t) if nameType == nil { @@ -26292,7 +26257,7 @@ func (c *Checker) getIndexTypeForMappedType(t *Type, indexFlags IndexFlags) *Typ // a circular definition. For this reason, we only eagerly manifest the keys if the constraint is non-generic. if c.isGenericIndexType(constraintType) { if c.isMappedTypeWithKeyofConstraintDeclaration(t) { - // We have a generic index and a homomorphic mapping (but a distributive key remapping) - we need to defer + // We have a generic index and a homomorphic mapping and a key remapping - we need to defer // the whole `keyof whatever` for later since it's not safe to resolve the shape of modifier type. return c.getIndexTypeForGenericType(t, indexFlags) } @@ -26829,16 +26794,13 @@ func (c *Checker) getBaseConstraintOrType(t *Type) *Type { } func (c *Checker) getBaseConstraintOfType(t *Type) *Type { - if t.flags&(TypeFlagsInstantiableNonPrimitive|TypeFlagsUnionOrIntersection|TypeFlagsTemplateLiteral|TypeFlagsStringMapping) != 0 || c.isGenericTupleType(t) { + if t.flags&(TypeFlagsInstantiableNonPrimitive|TypeFlagsUnionOrIntersection|TypeFlagsTemplateLiteral|TypeFlagsStringMapping|TypeFlagsIndex) != 0 || c.isGenericTupleType(t) { constraint := c.getResolvedBaseConstraint(t, nil) if constraint != c.noConstraintType && constraint != c.circularConstraintType { return constraint } return nil } - if t.flags&TypeFlagsIndex != 0 { - return c.stringNumberSymbolType - } return nil } @@ -26919,6 +26881,12 @@ func (c *Checker) computeBaseConstraint(t *Type, stack []RecursionId) *Type { } return nil case t.flags&TypeFlagsIndex != 0: + if c.isGenericMappedType(t.AsIndexType().target) { + mappedType := t.AsIndexType().target + if c.getNameTypeFromMappedType(mappedType) != nil && !c.isMappedTypeWithKeyofConstraintDeclaration(mappedType) { + return c.getNextBaseConstraint(c.getIndexTypeForMappedType(mappedType, IndexFlagsNone), stack) + } + } return c.stringNumberSymbolType case t.flags&TypeFlagsTemplateLiteral != 0: types := t.Types() diff --git a/internal/checker/types.go b/internal/checker/types.go index 3e2aafbd4c3..8900314987d 100644 --- a/internal/checker/types.go +++ b/internal/checker/types.go @@ -450,7 +450,7 @@ const ( TypeFlagsInstantiable = TypeFlagsInstantiableNonPrimitive | TypeFlagsInstantiablePrimitive TypeFlagsStructuredOrInstantiable = TypeFlagsStructuredType | TypeFlagsInstantiable TypeFlagsObjectFlagsType = TypeFlagsAny | TypeFlagsNullable | TypeFlagsNever | TypeFlagsObject | TypeFlagsUnion | TypeFlagsIntersection - TypeFlagsSimplifiable = TypeFlagsIndexedAccess | TypeFlagsConditional + TypeFlagsSimplifiable = TypeFlagsIndexedAccess | TypeFlagsConditional | TypeFlagsIndex TypeFlagsSingleton = TypeFlagsAny | TypeFlagsUnknown | TypeFlagsString | TypeFlagsNumber | TypeFlagsBoolean | TypeFlagsBigInt | TypeFlagsESSymbol | TypeFlagsVoid | TypeFlagsUndefined | TypeFlagsNull | TypeFlagsNever | TypeFlagsNonPrimitive // 'TypeFlagsNarrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never diff --git a/internal/testrunner/compiler_runner.go b/internal/testrunner/compiler_runner.go index 4c6b1ad752a..fc4a62a19a5 100644 --- a/internal/testrunner/compiler_runner.go +++ b/internal/testrunner/compiler_runner.go @@ -84,9 +84,6 @@ func (r *CompilerBaselineRunner) EnumerateTestFiles() []string { } var skippedTests = []string{ - // Broken until further porting work is done - "mappedTypeAsClauseRecursiveNoCrash1.ts", - // Flaky "for-of29.ts", diff --git a/testdata/baselines/reference/submodule/compiler/keyRemappingKeyofResult2.errors.txt b/testdata/baselines/reference/submodule/compiler/keyRemappingKeyofResult2.errors.txt deleted file mode 100644 index 6ee25e23d47..00000000000 --- a/testdata/baselines/reference/submodule/compiler/keyRemappingKeyofResult2.errors.txt +++ /dev/null @@ -1,51 +0,0 @@ -keyRemappingKeyofResult2.ts(23,7): error TS2344: Type 'Values<{ [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }>' does not satisfy the constraint 'ProvidedActor'. - Types of property 'src' are incompatible. - Type 'keyof { [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }' is not assignable to type 'string'. - Type 'string | number | symbol' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. - - -==== keyRemappingKeyofResult2.ts (1 errors) ==== - // https://github.com/microsoft/TypeScript/issues/56239 - - type Values = T[keyof T]; - - type ProvidedActor = { - src: string; - logic: unknown; - }; - - interface StateMachineConfig { - invoke: { - src: TActors["src"]; - }; - } - - declare function setup>(_: { - actors: { - [K in keyof TActors]: TActors[K]; - }; - }): { - createMachine: ( - config: StateMachineConfig< - Values<{ - ~~~~~~~~ - [K in keyof TActors as K & string]: { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - src: K; - ~~~~~~~~~~~~~~~~~ - logic: TActors[K]; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - }; - ~~~~~~~~~~ - }> - ~~~~~~~~ -!!! error TS2344: Type 'Values<{ [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }>' does not satisfy the constraint 'ProvidedActor'. -!!! error TS2344: Types of property 'src' are incompatible. -!!! error TS2344: Type 'keyof { [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }' is not assignable to type 'string'. -!!! error TS2344: Type 'string | number | symbol' is not assignable to type 'string'. -!!! error TS2344: Type 'number' is not assignable to type 'string'. - >, - ) => void; - }; - \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/compiler/keyRemappingKeyofResult2.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/keyRemappingKeyofResult2.errors.txt.diff deleted file mode 100644 index 44d7535e0fa..00000000000 --- a/testdata/baselines/reference/submodule/compiler/keyRemappingKeyofResult2.errors.txt.diff +++ /dev/null @@ -1,55 +0,0 @@ ---- old.keyRemappingKeyofResult2.errors.txt -+++ new.keyRemappingKeyofResult2.errors.txt -@@= skipped -0, +0 lines =@@ -- -+keyRemappingKeyofResult2.ts(23,7): error TS2344: Type 'Values<{ [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }>' does not satisfy the constraint 'ProvidedActor'. -+ Types of property 'src' are incompatible. -+ Type 'keyof { [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }' is not assignable to type 'string'. -+ Type 'string | number | symbol' is not assignable to type 'string'. -+ Type 'number' is not assignable to type 'string'. -+ -+ -+==== keyRemappingKeyofResult2.ts (1 errors) ==== -+ // https://github.com/microsoft/TypeScript/issues/56239 -+ -+ type Values = T[keyof T]; -+ -+ type ProvidedActor = { -+ src: string; -+ logic: unknown; -+ }; -+ -+ interface StateMachineConfig { -+ invoke: { -+ src: TActors["src"]; -+ }; -+ } -+ -+ declare function setup>(_: { -+ actors: { -+ [K in keyof TActors]: TActors[K]; -+ }; -+ }): { -+ createMachine: ( -+ config: StateMachineConfig< -+ Values<{ -+ ~~~~~~~~ -+ [K in keyof TActors as K & string]: { -+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ src: K; -+ ~~~~~~~~~~~~~~~~~ -+ logic: TActors[K]; -+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ }; -+ ~~~~~~~~~~ -+ }> -+ ~~~~~~~~ -+!!! error TS2344: Type 'Values<{ [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }>' does not satisfy the constraint 'ProvidedActor'. -+!!! error TS2344: Types of property 'src' are incompatible. -+!!! error TS2344: Type 'keyof { [K in keyof TActors as K & string]: { src: K; logic: TActors[K]; }; }' is not assignable to type 'string'. -+!!! error TS2344: Type 'string | number | symbol' is not assignable to type 'string'. -+!!! error TS2344: Type 'number' is not assignable to type 'string'. -+ >, -+ ) => void; -+ }; -+ \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/mappedTypeAsClauseRecursiveNoCrash1.symbols b/testdata/baselines/reference/submodule/conformance/mappedTypeAsClauseRecursiveNoCrash1.symbols new file mode 100644 index 00000000000..2aa6ec2b1a5 --- /dev/null +++ b/testdata/baselines/reference/submodule/conformance/mappedTypeAsClauseRecursiveNoCrash1.symbols @@ -0,0 +1,121 @@ +//// [tests/cases/conformance/types/mapped/mappedTypeAsClauseRecursiveNoCrash1.ts] //// + +=== mappedTypeAsClauseRecursiveNoCrash1.ts === +// https://github.com/microsoft/TypeScript/issues/60476 + +export type FlattenType = { +>FlattenType : Symbol(FlattenType, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 0, 0)) +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 24)) +>Target : Symbol(Target, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 46)) + + [Key in keyof Source as Key extends string +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 3, 3)) +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 24)) +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 3, 3)) + + ? Source[Key] extends object +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 24)) +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 3, 3)) + + ? `${Key}.${keyof FlattenType & string}` +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 3, 3)) +>FlattenType : Symbol(FlattenType, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 0, 0)) +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 24)) +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 3, 3)) +>Target : Symbol(Target, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 46)) + + : Key +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 3, 3)) + + : never]-?: Target; +>Target : Symbol(Target, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 2, 46)) + +}; + +type FieldSelect = { +>FieldSelect : Symbol(FieldSelect, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 8, 2)) + + table: string; +>table : Symbol(table, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 10, 20)) + + field: string; +>field : Symbol(field, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 11, 16)) + +}; + +type Address = { +>Address : Symbol(Address, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 13, 2)) + + postCode: string; +>postCode : Symbol(postCode, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 15, 16)) + + description: string; +>description : Symbol(description, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 16, 19)) + + address: string; +>address : Symbol(address, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 17, 22)) + +}; + +type User = { +>User : Symbol(User, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 19, 2)) + + id: number; +>id : Symbol(id, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 21, 13)) + + name: string; +>name : Symbol(name, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 22, 13)) + + address: Address; +>address : Symbol(address, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 23, 15)) +>Address : Symbol(Address, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 13, 2)) + +}; + +type FlattenedUser = FlattenType; +>FlattenedUser : Symbol(FlattenedUser, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 25, 2)) +>FlattenType : Symbol(FlattenType, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 0, 0)) +>User : Symbol(User, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 19, 2)) +>FieldSelect : Symbol(FieldSelect, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 8, 2)) + +type FlattenedUserKeys = keyof FlattenType; +>FlattenedUserKeys : Symbol(FlattenedUserKeys, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 27, 52)) +>FlattenType : Symbol(FlattenType, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 0, 0)) +>User : Symbol(User, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 19, 2)) +>FieldSelect : Symbol(FieldSelect, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 8, 2)) + +export type FlattenTypeKeys = keyof { +>FlattenTypeKeys : Symbol(FlattenTypeKeys, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 28, 62)) +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 28)) +>Target : Symbol(Target, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 50)) + + [Key in keyof Source as Key extends string +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 31, 3)) +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 28)) +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 31, 3)) + + ? Source[Key] extends object +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 28)) +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 31, 3)) + + ? `${Key}.${keyof FlattenType & string}` +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 31, 3)) +>FlattenType : Symbol(FlattenType, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 0, 0)) +>Source : Symbol(Source, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 28)) +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 31, 3)) +>Target : Symbol(Target, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 50)) + + : Key +>Key : Symbol(Key, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 31, 3)) + + : never]-?: Target; +>Target : Symbol(Target, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 30, 50)) + +}; + +type FlattenedUserKeys2 = FlattenTypeKeys; +>FlattenedUserKeys2 : Symbol(FlattenedUserKeys2, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 36, 2)) +>FlattenTypeKeys : Symbol(FlattenTypeKeys, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 28, 62)) +>User : Symbol(User, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 19, 2)) +>FieldSelect : Symbol(FieldSelect, Decl(mappedTypeAsClauseRecursiveNoCrash1.ts, 8, 2)) + diff --git a/testdata/baselines/reference/submodule/conformance/mappedTypeAsClauseRecursiveNoCrash1.types b/testdata/baselines/reference/submodule/conformance/mappedTypeAsClauseRecursiveNoCrash1.types new file mode 100644 index 00000000000..cfd1546d3d3 --- /dev/null +++ b/testdata/baselines/reference/submodule/conformance/mappedTypeAsClauseRecursiveNoCrash1.types @@ -0,0 +1,73 @@ +//// [tests/cases/conformance/types/mapped/mappedTypeAsClauseRecursiveNoCrash1.ts] //// + +=== mappedTypeAsClauseRecursiveNoCrash1.ts === +// https://github.com/microsoft/TypeScript/issues/60476 + +export type FlattenType = { +>FlattenType : FlattenType + + [Key in keyof Source as Key extends string + ? Source[Key] extends object + ? `${Key}.${keyof FlattenType & string}` + : Key + : never]-?: Target; +}; + +type FieldSelect = { +>FieldSelect : FieldSelect + + table: string; +>table : string + + field: string; +>field : string + +}; + +type Address = { +>Address : Address + + postCode: string; +>postCode : string + + description: string; +>description : string + + address: string; +>address : string + +}; + +type User = { +>User : User + + id: number; +>id : number + + name: string; +>name : string + + address: Address; +>address : Address + +}; + +type FlattenedUser = FlattenType; +>FlattenedUser : FlattenType + +type FlattenedUserKeys = keyof FlattenType; +>FlattenedUserKeys : "address.address" | "address.description" | "address.postCode" | "id" | "name" + +export type FlattenTypeKeys = keyof { +>FlattenTypeKeys : keyof { [Key in keyof Source as Key extends string ? Source[Key] extends object ? `${Key}.${keyof FlattenType & string}` : Key : never]-?: Target; } + + [Key in keyof Source as Key extends string + ? Source[Key] extends object + ? `${Key}.${keyof FlattenType & string}` + : Key + : never]-?: Target; +}; + +type FlattenedUserKeys2 = FlattenTypeKeys; +>FlattenedUserKeys2 : "address.address" | "address.description" | "address.postCode" | "id" | "name" + diff --git a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt index bfc0fcbb830..bc2f5287b0a 100644 --- a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt +++ b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt @@ -4,17 +4,14 @@ mappedTypeConstraints2.ts(16,11): error TS2322: Type 'Mapped3[Uppercase]' Type 'Mapped3[Uppercase]' is not assignable to type '{ a: K; }'. Type 'Mapped3[string]' is not assignable to type '{ a: K; }'. mappedTypeConstraints2.ts(42,7): error TS2322: Type 'Mapped6[keyof Mapped6]' is not assignable to type '`_${string}`'. - Type 'Mapped6[string] | Mapped6[number] | Mapped6[symbol]' is not assignable to type '`_${string}`'. - Type 'Mapped6[string]' is not assignable to type '`_${string}`'. -mappedTypeConstraints2.ts(50,7): error TS2322: Type 'string | number | symbol' is not assignable to type '`_${string}`'. - Type 'string' is not assignable to type '`_${string}`'. + Type 'Mapped6[`_${string}`]' is not assignable to type '`_${string}`'. mappedTypeConstraints2.ts(59,57): error TS2322: Type 'Foo[`get${T}`]' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Foo[`get${T}`]'. mappedTypeConstraints2.ts(90,9): error TS2322: Type 'ObjectWithUnderscoredKeys[`_${K}`]' is not assignable to type 'true'. Type 'ObjectWithUnderscoredKeys[`_${string}`]' is not assignable to type 'true'. -==== mappedTypeConstraints2.ts (6 errors) ==== +==== mappedTypeConstraints2.ts (5 errors) ==== type Mapped1 = { [P in K]: { a: P } }; function f1(obj: Mapped1, key: K) { @@ -66,8 +63,7 @@ mappedTypeConstraints2.ts(90,9): error TS2322: Type 'ObjectWithUnderscoredKeys[keyof Mapped6]' is not assignable to type '`_${string}`'. -!!! error TS2322: Type 'Mapped6[string] | Mapped6[number] | Mapped6[symbol]' is not assignable to type '`_${string}`'. -!!! error TS2322: Type 'Mapped6[string]' is not assignable to type '`_${string}`'. +!!! error TS2322: Type 'Mapped6[`_${string}`]' is not assignable to type '`_${string}`'. } type Mapped7 = { @@ -76,9 +72,6 @@ mappedTypeConstraints2.ts(90,9): error TS2322: Type 'ObjectWithUnderscoredKeys(obj: Mapped7, key: keyof Mapped7) { let s: `_${string}` = obj[key]; - ~ -!!! error TS2322: Type 'string | number | symbol' is not assignable to type '`_${string}`'. -!!! error TS2322: Type 'string' is not assignable to type '`_${string}`'. } // Repro from #47794 diff --git a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt.diff b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt.diff index 08ef2058b9f..6706bb75872 100644 --- a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt.diff +++ b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.errors.txt.diff @@ -6,39 +6,17 @@ mappedTypeConstraints2.ts(42,7): error TS2322: Type 'Mapped6[keyof Mapped6]' is not assignable to type '`_${string}`'. - Type 'Mapped6[`_${K}`]' is not assignable to type '`_${string}`'. - Type 'Mapped6[`_${string}`]' is not assignable to type '`_${string}`'. -+ Type 'Mapped6[string] | Mapped6[number] | Mapped6[symbol]' is not assignable to type '`_${string}`'. -+ Type 'Mapped6[string]' is not assignable to type '`_${string}`'. -+mappedTypeConstraints2.ts(50,7): error TS2322: Type 'string | number | symbol' is not assignable to type '`_${string}`'. -+ Type 'string' is not assignable to type '`_${string}`'. ++ Type 'Mapped6[`_${string}`]' is not assignable to type '`_${string}`'. mappedTypeConstraints2.ts(59,57): error TS2322: Type 'Foo[`get${T}`]' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Foo[`get${T}`]'. mappedTypeConstraints2.ts(90,9): error TS2322: Type 'ObjectWithUnderscoredKeys[`_${K}`]' is not assignable to type 'true'. - Type 'ObjectWithUnderscoredKeys[`_${string}`]' is not assignable to type 'true'. - - --==== mappedTypeConstraints2.ts (5 errors) ==== -+==== mappedTypeConstraints2.ts (6 errors) ==== - type Mapped1 = { [P in K]: { a: P } }; - - function f1(obj: Mapped1, key: K) { -@@= skipped -60, +62 lines =@@ +@@= skipped -60, +59 lines =@@ let s: `_${string}` = obj[key]; // Error ~ !!! error TS2322: Type 'Mapped6[keyof Mapped6]' is not assignable to type '`_${string}`'. -!!! error TS2322: Type 'Mapped6[`_${K}`]' is not assignable to type '`_${string}`'. -!!! error TS2322: Type 'Mapped6[`_${string}`]' is not assignable to type '`_${string}`'. -+!!! error TS2322: Type 'Mapped6[string] | Mapped6[number] | Mapped6[symbol]' is not assignable to type '`_${string}`'. -+!!! error TS2322: Type 'Mapped6[string]' is not assignable to type '`_${string}`'. - } - - type Mapped7 = { -@@= skipped -10, +10 lines =@@ - - function f7(obj: Mapped7, key: keyof Mapped7) { - let s: `_${string}` = obj[key]; -+ ~ -+!!! error TS2322: Type 'string | number | symbol' is not assignable to type '`_${string}`'. -+!!! error TS2322: Type 'string' is not assignable to type '`_${string}`'. ++!!! error TS2322: Type 'Mapped6[`_${string}`]' is not assignable to type '`_${string}`'. } - // Repro from #47794 \ No newline at end of file + type Mapped7 = { \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types index 23e57759a7c..98ba265c1a1 100644 --- a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types +++ b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types @@ -77,15 +77,15 @@ type Mapped5 = { }; function f5(obj: Mapped5, key: keyof Mapped5) { ->f5 : (obj: Mapped5, key: K extends `_${string}` ? K : never) => void +>f5 : (obj: Mapped5, key: keyof Mapped5) => void >obj : Mapped5 ->key : K extends `_${string}` ? K : never +>key : keyof Mapped5 let s: `_${string}` = obj[key]; >s : `_${string}` ->obj[key] : Mapped5[K extends `_${string}` ? K : never] +>obj[key] : Mapped5[keyof Mapped5] >obj : Mapped5 ->key : K extends `_${string}` ? K : never +>key : keyof Mapped5 } // repro from #53066#issuecomment-1913384757 @@ -121,7 +121,7 @@ function f7(obj: Mapped7, key: keyof Mapped7) { let s: `_${string}` = obj[key]; >s : `_${string}` ->obj[key] : string | number | symbol +>obj[key] : Mapped7[keyof Mapped7] >obj : Mapped7 >key : keyof Mapped7 } diff --git a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types.diff b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types.diff index c3d65cee6f9..79013af57bf 100644 --- a/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types.diff +++ b/testdata/baselines/reference/submodule/conformance/mappedTypeConstraints2.types.diff @@ -9,36 +9,7 @@ >obj : Mapped4 >key : K -@@= skipped -18, +18 lines =@@ - }; - - function f5(obj: Mapped5, key: keyof Mapped5) { -->f5 : (obj: Mapped5, key: keyof Mapped5) => void -+>f5 : (obj: Mapped5, key: K extends `_${string}` ? K : never) => void - >obj : Mapped5 -->key : keyof Mapped5 -+>key : K extends `_${string}` ? K : never - - let s: `_${string}` = obj[key]; - >s : `_${string}` -->obj[key] : Mapped5[keyof Mapped5] -+>obj[key] : Mapped5[K extends `_${string}` ? K : never] - >obj : Mapped5 -->key : keyof Mapped5 -+>key : K extends `_${string}` ? K : never - } - - // repro from #53066#issuecomment-1913384757 -@@= skipped -44, +44 lines =@@ - - let s: `_${string}` = obj[key]; - >s : `_${string}` -->obj[key] : Mapped7[keyof Mapped7] -+>obj[key] : string | number | symbol - >obj : Mapped7 - >key : keyof Mapped7 - } -@@= skipped -48, +48 lines =@@ +@@= skipped -110, +110 lines =@@ >key : string >val : any >Object.entries(obj) : [string, any][]