diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 950b9a8e30fb8..79e26f506bd22 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -17675,6 +17675,9 @@ func (c *Checker) getConstraintFromIndexedAccess(t *Type) *Type { // we substitute an instantiation of E where P is replaced with X. return c.substituteIndexedMappedType(d.objectType, d.indexType) } + if constraint := c.getConstraintOfMappedTypeIntersectionIndexedAccess(t); constraint != nil { + return constraint + } indexConstraint := c.getSimplifiedTypeOrConstraint(d.indexType) if indexConstraint != nil && indexConstraint != d.indexType { indexedAccess := c.getIndexedAccessTypeOrUndefined(d.objectType, indexConstraint, d.accessFlags, nil, nil) @@ -17689,6 +17692,87 @@ func (c *Checker) getConstraintFromIndexedAccess(t *Type) *Type { return nil } +// For an indexed access (A & B)[X] with a generic index X, a generic mapped type { [P in K]: E } in the intersection only +// contributes E for keys in K. Resolving X to a non-generic constraint (e.g. string) would make every such mapped type +// contribute E, giving (Record & Record)[K1] the constraint T & U instead of T, so we first drop the mapped +// types not known to contain X. Resolving X to a generic constraint C is sound since these rules apply again to +// (A & B)[C], but we retain E for the mapped types known to contain X and not C, as they would otherwise be dropped. +// Possibly numeric keys are excluded, as they may select the same properties as differently represented string keys. +func (c *Checker) getConstraintOfMappedTypeIntersectionIndexedAccess(t *Type) *Type { + d := t.AsIndexedAccessType() + if d.objectType.flags&TypeFlagsIntersection == 0 || !c.isGenericIndexType(d.indexType) || c.isPossiblyNumericKeyType(d.indexType) { + return nil + } + types := d.objectType.Types() + if !core.Some(types, c.isGenericMappedType) || core.Some(types, func(s *Type) bool { + return c.isGenericMappedType(s) && c.isPossiblyNumericKeyType(c.getIndexType(s)) + }) { + return nil + } + indexConstraint := c.getSimplifiedTypeOrConstraint(d.indexType) + if indexConstraint == nil || indexConstraint == d.indexType { + return nil + } + isGenericConstraint := c.isGenericIndexType(indexConstraint) + var retainedTypes []*Type + if isGenericConstraint { + for _, s := range types { + if c.isGenericMappedType(s) && c.isKnownKeyOfType(d.indexType, s) && !c.isKnownKeyOfType(indexConstraint, s) { + retainedTypes = append(retainedTypes, c.getSimplifiedType(c.getIndexedAccessTypeEx(s, d.indexType, d.accessFlags, nil, nil), false /*writing*/)) + } + } + } + // We resolve each non-generic constituent of the constraint separately, as different members of the intersection may + // contain different constituents. For example, given X extends "a" | "b", only { b: U } contains "b" in + // (Record & { b: U })[X]. When the constraint isn't a union, we index the remaining members by X itself. + // When no members remain, X isn't known to be a key of any of them, and the constraint is unknown. + changed := false + widenedType := c.mapType(indexConstraint, func(key *Type) *Type { + if !c.isGenericIndexType(key) { + remainingTypes := core.Filter(types, func(s *Type) bool { + return !c.isGenericMappedType(s) || c.isKnownKeyOfType(d.indexType, s) || c.isKnownKeyOfType(key, s) + }) + if len(remainingTypes) < len(types) { + changed = true + if len(remainingTypes) == 0 { + return c.unknownType + } + return c.getIndexedAccessTypeEx(c.getIntersectionType(remainingTypes), core.IfElse(indexConstraint.flags&TypeFlagsUnion != 0, key, d.indexType), d.accessFlags, nil, nil) + } + } + return c.getIndexedAccessTypeEx(d.objectType, key, d.accessFlags, nil, nil) + }) + if !changed { + if !isGenericConstraint { + return nil + } + // We return (A & B)[C] even when nothing changed, such that base constraint computation applies these rules to + // it instead of resolving X to its base constraint directly. + widenedType = c.getIndexedAccessTypeEx(d.objectType, indexConstraint, d.accessFlags, nil, nil) + } + return c.getIntersectionType(append(retainedTypes, widenedType)) +} + +func (c *Checker) isPossiblyNumericKeyType(t *Type) bool { + return c.maybeTypeOfKind(c.getBaseConstraintOrType(t), TypeFlagsNumberLike) +} + +// Return true if the given index type is known to be a key of the given type. A string key and its template literal +// representation (e.g. K and `${K}`) select the same properties, so we also compare those representations. +func (c *Checker) isKnownKeyOfType(indexType *Type, t *Type) bool { + keyType := c.getIndexType(t) + return c.isTypeAssignableTo(indexType, keyType) || c.isTypeAssignableTo(c.getTemplateLiteralKeyType(indexType), c.getTemplateLiteralKeyType(keyType)) +} + +func (c *Checker) getTemplateLiteralKeyType(t *Type) *Type { + return c.mapType(t, func(t *Type) *Type { + if c.isTypeAssignableToKind(t, TypeFlagsStringLike) { + return c.getTemplateLiteralType([]string{"", ""}, []*Type{t}) + } + return t + }) +} + func (c *Checker) getConstraintOfConditionalType(t *Type) *Type { if c.hasNonCircularBaseConstraint(t) { return c.getConstraintFromConditionalType(t) @@ -28333,6 +28417,9 @@ func (c *Checker) computeBaseConstraint(t *Type, stack []RecursionId) *Type { // we substitute an instantiation of E where P is replaced with X. return c.getNextBaseConstraint(c.substituteIndexedMappedType(t.AsIndexedAccessType().objectType, t.AsIndexedAccessType().indexType), stack) } + if constraint := c.getConstraintOfMappedTypeIntersectionIndexedAccess(t); constraint != nil { + return c.getNextBaseConstraint(constraint, stack) + } baseObjectType := c.getNextBaseConstraint(t.AsIndexedAccessType().objectType, stack) baseIndexType := c.getNextBaseConstraint(t.AsIndexedAccessType().indexType, stack) if baseObjectType == nil || baseIndexType == nil { diff --git a/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.errors.txt b/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.errors.txt new file mode 100644 index 0000000000000..ec50a445f92db --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.errors.txt @@ -0,0 +1,232 @@ +genericRecordIntersectionAssignability.ts(4,5): error TS2322: Type 'Record & Record' is not assignable to type 'Record'. +genericRecordIntersectionAssignability.ts(18,11): error TS2322: Type '(Record & Record)[K1]' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +genericRecordIntersectionAssignability.ts(19,11): error TS2322: Type '(Record & Record)[K2]' is not assignable to type 'T & U'. + Type 'U' is not assignable to type 'T & U'. + Type 'U' is not assignable to type 'T'. + 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. +genericRecordIntersectionAssignability.ts(24,11): error TS2339: Property 'b' does not exist on type '(Record & Record)[K1]'. +genericRecordIntersectionAssignability.ts(25,11): error TS2339: Property 'a' does not exist on type '(Record & Record)[K2]'. +genericRecordIntersectionAssignability.ts(33,11): error TS2322: Type '(Record & Record)[K1]' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +genericRecordIntersectionAssignability.ts(38,11): error TS2322: Type '(Record & Record & { extra: V; })[K1]' is not assignable to type 'T & U'. + Type '(Record & { extra: V; })[K1]' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +genericRecordIntersectionAssignability.ts(43,11): error TS2322: Type '(Record & Record & { [key: string]: V; })[K1]' is not assignable to type 'T & U'. + Type '(Record & { [key: string]: V; })[K1]' is not assignable to type 'T & U'. + Type 'T & V' is not assignable to type 'T & U'. + Type 'T & V' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T & V'. +genericRecordIntersectionAssignability.ts(56,11): error TS2322: Type '(Record & { a: T; })[K]' is not assignable to type 'T & U'. + Type '{ a: T; }[K]' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +genericRecordIntersectionAssignability.ts(72,5): error TS2322: Type '({ [P in `${X}`]: P; } & Record)[X]' is not assignable to type 'X'. + '({ [P in `${X}`]: P; } & Record)[X]' is assignable to the constraint of type 'X', but 'X' could be instantiated with a different subtype of constraint 'number'. + Type '({ [P in `${X}`]: P; } & Record)[K]' is not assignable to type 'X'. + '({ [P in `${X}`]: P; } & Record)[K]' is assignable to the constraint of type 'X', but 'X' could be instantiated with a different subtype of constraint 'number'. + Type 'number' is not assignable to type 'X'. + 'number' is assignable to the constraint of type 'X', but 'X' could be instantiated with a different subtype of constraint 'number'. +genericRecordIntersectionAssignability.ts(89,11): error TS2322: Type '(Record & Record & { b: T; })[X]' is not assignable to type 'T & U'. + Type 'T | (Record & Record & { b: T; })[K1]' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'T & U'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +genericRecordIntersectionAssignability.ts(93,5): error TS2322: Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +genericRecordIntersectionAssignability.ts(98,10): error TS2339: Property 'b' does not exist on type '(Record & Record)[X]'. +genericRecordIntersectionAssignability.ts(103,11): error TS2322: Type '(Record & Record)[X]' is not assignable to type 'T & U'. + Type 'T & (Record & Record)[K]' is not assignable to type 'T & U'. + Type 'T & (Record & Record)[K]' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T & (Record & Record)[K]'. + + +==== genericRecordIntersectionAssignability.ts (14 errors) ==== + // https://github.com/microsoft/TypeScript/issues/64495 + + function f1(x: Record & Record): Record { + return x; // Error + ~~~~~~ +!!! error TS2322: Type 'Record & Record' is not assignable to type 'Record'. + } + + function f2(x: Record & Record): Record { + return x; + } + + function f3(x: Record & Record): Record { + return x; + } + + function f4(x: Record & Record, k1: K1, k2: K2) { + const t: T = x[k1]; + const u: U = x[k2]; + const tu1: T & U = x[k1]; // Error + ~~~ +!!! error TS2322: Type '(Record & Record)[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 genericRecordIntersectionAssignability.ts:15:32: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:15:32: This type parameter might need an `extends U` constraint. + const tu2: T & U = x[k2]; // Error + ~~~ +!!! error TS2322: Type '(Record & Record)[K2]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'U' is not assignable to type 'T & U'. +!!! error TS2322: Type 'U' is not assignable to type 'T'. +!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. +!!! related TS2208 genericRecordIntersectionAssignability.ts:15:54: This type parameter might need an `extends T` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:15:54: This type parameter might need an `extends T` constraint. + } + + function f5(x: Record & Record, k1: K1, k2: K2) { + x[k1].a; + x[k1].b; // Error + ~ +!!! error TS2339: Property 'b' does not exist on type '(Record & Record)[K1]'. + x[k2].a; // Error + ~ +!!! error TS2339: Property 'a' does not exist on type '(Record & Record)[K2]'. + x[k2].b; + } + + function f6(x: Record & Record, k1: K1, k2: K2) { + const t: T = x[k2]; + const u: U = x[k2]; + const tu: T & U = x[k2]; + const tu1: T & U = x[k1]; // Error + ~~~ +!!! error TS2322: Type '(Record & Record)[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 genericRecordIntersectionAssignability.ts:29:32: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:29:32: This type parameter might need an `extends U` constraint. + } + + function f7(x: Record & Record & { extra: V }, k1: K1) { + const t: T = x[k1]; + const tu: T & U = x[k1]; // Error + ~~ +!!! error TS2322: Type '(Record & Record & { extra: V; })[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type '(Record & { extra: V; })[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 genericRecordIntersectionAssignability.ts:36:32: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:36:32: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:36:32: This type parameter might need an `extends U` constraint. + } + + function f8(x: Record & Record & { [key: string]: V }, k1: K1) { + const tv: T & V = x[k1]; + const tu: T & U = x[k1]; // Error + ~~ +!!! error TS2322: Type '(Record & Record & { [key: string]: V; })[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type '(Record & { [key: string]: V; })[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T & V' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T & V' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T & V'. + } + + function f9(x: Record & Record & Record, k3: K3) { + const n: number = x[k3]; + } + + function f10(x: Record & Record & Record, k1: K1) { + const tv: T & V = x[k1]; + } + + function f11(x: Record & { a: T }, k: K) { + const t: T = x[k]; + const tu: T & U = x[k]; // Error + ~~ +!!! error TS2322: Type '(Record & { a: T; })[K]' is not assignable to type 'T & U'. +!!! error TS2322: Type '{ a: T; }[K]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 genericRecordIntersectionAssignability.ts:54:29: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:54:29: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:54:29: This type parameter might need an `extends U` constraint. + } + + function f12(x: Record & { metadata: number }, k: X): T | U { + return x[k]; + } + + function f13(x: Record & Record<`${K}`, T>, k: K): T { + return x[k]; + } + + function f14(x: Record & Record<`${K}`, unknown>, k: `${K}`): number { + return x[k]; + } + + function f15(x: { [P in `${X}`]: P } & Record, k: X): X { + return x[k]; // Error + ~~~~~~ +!!! error TS2322: Type '({ [P in `${X}`]: P; } & Record)[X]' is not assignable to type 'X'. +!!! error TS2322: '({ [P in `${X}`]: P; } & Record)[X]' is assignable to the constraint of type 'X', but 'X' could be instantiated with a different subtype of constraint 'number'. +!!! error TS2322: Type '({ [P in `${X}`]: P; } & Record)[K]' is not assignable to type 'X'. +!!! error TS2322: '({ [P in `${X}`]: P; } & Record)[K]' is assignable to the constraint of type 'X', but 'X' could be instantiated with a different subtype of constraint 'number'. +!!! error TS2322: Type 'number' is not assignable to type 'X'. +!!! error TS2322: 'number' is assignable to the constraint of type 'X', but 'X' could be instantiated with a different subtype of constraint 'number'. + } + + function f16(x: Record & Record<`${K}`, number>, k: K): number { + return x[k]; + } + + function f17(x: Record & Record<`${X}`, number>, k: X): number { + return x[k]; + } + + function f18(x: Record & { b: number }, k: X): number { + return x[k]; + } + + function f19(x: Record & Record & { b: T }, k: X) { + const t: T = x[k]; + const tu: T & U = x[k]; // Error + ~~ +!!! error TS2322: Type '(Record & Record & { b: T; })[X]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T | (Record & Record & { b: T; })[K1]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 genericRecordIntersectionAssignability.ts:87:33: This type parameter might need an `extends U` constraint. +!!! related TS2208 genericRecordIntersectionAssignability.ts:87:33: This type parameter might need an `extends U` constraint. + } + + function f20(x: Record & Record & { b: string }, k: X): number { + return x[k]; // Error + ~~~~~~ +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + } + + function f21(x: Record & Record, k: X) { + x[k].a; + x[k].b; // Error + ~ +!!! error TS2339: Property 'b' does not exist on type '(Record & Record)[X]'. + } + + function f22(x: Record & Record, k: X) { + const t: T = x[k]; + const tu: T & U = x[k]; // Error + ~~ +!!! error TS2322: Type '(Record & Record)[X]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T & (Record & Record)[K]' is not assignable to type 'T & U'. +!!! error TS2322: Type 'T & (Record & Record)[K]' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T & (Record & Record)[K]'. + } + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.symbols b/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.symbols new file mode 100644 index 0000000000000..9e8557a109662 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.symbols @@ -0,0 +1,591 @@ +//// [tests/cases/compiler/genericRecordIntersectionAssignability.ts] //// + +=== genericRecordIntersectionAssignability.ts === +// https://github.com/microsoft/TypeScript/issues/64495 + +function f1(x: Record & Record): Record { +>f1 : Symbol(f1, Decl(genericRecordIntersectionAssignability.ts, 0, 0)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 2, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 2, 30)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 2, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 2, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 2, 56)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 2, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 2, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 2, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 2, 52)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 2, 12)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 2, 33)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 2, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 2, 52)) + + return x; // Error +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 2, 56)) +} + +function f2(x: Record & Record): Record { +>f2 : Symbol(f2, Decl(genericRecordIntersectionAssignability.ts, 4, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 6, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 6, 30)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 6, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 6, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 6, 56)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 6, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 6, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 6, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 6, 52)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 6, 12)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 6, 33)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 6, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 6, 52)) + + return x; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 6, 56)) +} + +function f3(x: Record & Record): Record { +>f3 : Symbol(f3, Decl(genericRecordIntersectionAssignability.ts, 8, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 10, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 10, 29)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 10, 32)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 10, 36)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 10, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 10, 29)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 10, 12)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 10, 32)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 10, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 10, 29)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 10, 32)) + + return x; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 10, 36)) +} + +function f4(x: Record & Record, k1: K1, k2: K2) { +>f4 : Symbol(f4, Decl(genericRecordIntersectionAssignability.ts, 12, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 14, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 14, 30)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 14, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 14, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 14, 56)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 14, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 14, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 14, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 14, 52)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 14, 89)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 14, 12)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 14, 97)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 14, 33)) + + const t: T = x[k1]; +>t : Symbol(t, Decl(genericRecordIntersectionAssignability.ts, 15, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 14, 30)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 14, 56)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 14, 89)) + + const u: U = x[k2]; +>u : Symbol(u, Decl(genericRecordIntersectionAssignability.ts, 16, 9)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 14, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 14, 56)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 14, 97)) + + const tu1: T & U = x[k1]; // Error +>tu1 : Symbol(tu1, Decl(genericRecordIntersectionAssignability.ts, 17, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 14, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 14, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 14, 56)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 14, 89)) + + const tu2: T & U = x[k2]; // Error +>tu2 : Symbol(tu2, Decl(genericRecordIntersectionAssignability.ts, 18, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 14, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 14, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 14, 56)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 14, 97)) +} + +function f5(x: Record & Record, k1: K1, k2: K2) { +>f5 : Symbol(f5, Decl(genericRecordIntersectionAssignability.ts, 19, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 21, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 21, 30)) +>a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 21, 42)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 21, 55)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 21, 74)) +>b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 21, 86)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 21, 100)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 21, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 21, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 21, 55)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 21, 74)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 21, 133)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 21, 12)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 21, 141)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 21, 55)) + + x[k1].a; +>x[k1].a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 21, 42)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 21, 100)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 21, 133)) +>a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 21, 42)) + + x[k1].b; // Error +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 21, 100)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 21, 133)) + + x[k2].a; // Error +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 21, 100)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 21, 141)) + + x[k2].b; +>x[k2].b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 21, 86)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 21, 100)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 21, 141)) +>b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 21, 86)) +} + +function f6(x: Record & Record, k1: K1, k2: K2) { +>f6 : Symbol(f6, Decl(genericRecordIntersectionAssignability.ts, 26, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 28, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 28, 30)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 28, 33)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 28, 12)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 28, 48)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 28, 52)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 28, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 28, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 28, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 28, 48)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 28, 85)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 28, 12)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 28, 93)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 28, 33)) + + const t: T = x[k2]; +>t : Symbol(t, Decl(genericRecordIntersectionAssignability.ts, 29, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 28, 30)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 28, 52)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 28, 93)) + + const u: U = x[k2]; +>u : Symbol(u, Decl(genericRecordIntersectionAssignability.ts, 30, 9)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 28, 48)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 28, 52)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 28, 93)) + + const tu: T & U = x[k2]; +>tu : Symbol(tu, Decl(genericRecordIntersectionAssignability.ts, 31, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 28, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 28, 48)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 28, 52)) +>k2 : Symbol(k2, Decl(genericRecordIntersectionAssignability.ts, 28, 93)) + + const tu1: T & U = x[k1]; // Error +>tu1 : Symbol(tu1, Decl(genericRecordIntersectionAssignability.ts, 32, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 28, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 28, 48)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 28, 52)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 28, 85)) +} + +function f7(x: Record & Record & { extra: V }, k1: K1) { +>f7 : Symbol(f7, Decl(genericRecordIntersectionAssignability.ts, 33, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 35, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 35, 30)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 35, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 35, 52)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 35, 55)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 35, 59)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 35, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 35, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 35, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 35, 52)) +>extra : Symbol(extra, Decl(genericRecordIntersectionAssignability.ts, 35, 95)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 35, 55)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 35, 107)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 35, 12)) + + const t: T = x[k1]; +>t : Symbol(t, Decl(genericRecordIntersectionAssignability.ts, 36, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 35, 30)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 35, 59)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 35, 107)) + + const tu: T & U = x[k1]; // Error +>tu : Symbol(tu, Decl(genericRecordIntersectionAssignability.ts, 37, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 35, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 35, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 35, 59)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 35, 107)) +} + +function f8(x: Record & Record & { [key: string]: V }, k1: K1) { +>f8 : Symbol(f8, Decl(genericRecordIntersectionAssignability.ts, 38, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 40, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 40, 30)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 40, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 40, 52)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 40, 55)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 40, 59)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 40, 12)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 40, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 40, 33)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 40, 52)) +>key : Symbol(key, Decl(genericRecordIntersectionAssignability.ts, 40, 97)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 40, 55)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 40, 115)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 40, 12)) + + const tv: T & V = x[k1]; +>tv : Symbol(tv, Decl(genericRecordIntersectionAssignability.ts, 41, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 40, 30)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 40, 55)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 40, 59)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 40, 115)) + + const tu: T & U = x[k1]; // Error +>tu : Symbol(tu, Decl(genericRecordIntersectionAssignability.ts, 42, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 40, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 40, 52)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 40, 59)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 40, 115)) +} + +function f9(x: Record & Record & Record, k3: K3) { +>f9 : Symbol(f9, Decl(genericRecordIntersectionAssignability.ts, 43, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 45, 12)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 45, 30)) +>K3 : Symbol(K3, Decl(genericRecordIntersectionAssignability.ts, 45, 49)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 45, 12)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 45, 30)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 45, 70)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 45, 12)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 45, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K3 : Symbol(K3, Decl(genericRecordIntersectionAssignability.ts, 45, 49)) +>k3 : Symbol(k3, Decl(genericRecordIntersectionAssignability.ts, 45, 135)) +>K3 : Symbol(K3, Decl(genericRecordIntersectionAssignability.ts, 45, 49)) + + const n: number = x[k3]; +>n : Symbol(n, Decl(genericRecordIntersectionAssignability.ts, 46, 9)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 45, 70)) +>k3 : Symbol(k3, Decl(genericRecordIntersectionAssignability.ts, 45, 135)) +} + +function f10(x: Record & Record & Record, k1: K1) { +>f10 : Symbol(f10, Decl(genericRecordIntersectionAssignability.ts, 47, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 49, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 49, 31)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 49, 34)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 49, 53)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 49, 56)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 49, 60)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 49, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 49, 31)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 49, 34)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 49, 53)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 49, 56)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 49, 113)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 49, 13)) + + const tv: T & V = x[k1]; +>tv : Symbol(tv, Decl(genericRecordIntersectionAssignability.ts, 50, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 49, 31)) +>V : Symbol(V, Decl(genericRecordIntersectionAssignability.ts, 49, 56)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 49, 60)) +>k1 : Symbol(k1, Decl(genericRecordIntersectionAssignability.ts, 49, 113)) +} + +function f11(x: Record & { a: T }, k: K) { +>f11 : Symbol(f11, Decl(genericRecordIntersectionAssignability.ts, 51, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 53, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 53, 27)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 53, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 53, 49)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 53, 53)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 53, 30)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 53, 49)) +>a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 53, 73)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 53, 27)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 53, 81)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 53, 13)) + + const t: T = x[k]; +>t : Symbol(t, Decl(genericRecordIntersectionAssignability.ts, 54, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 53, 27)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 53, 53)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 53, 81)) + + const tu: T & U = x[k]; // Error +>tu : Symbol(tu, Decl(genericRecordIntersectionAssignability.ts, 55, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 53, 27)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 53, 49)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 53, 53)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 53, 81)) +} + +function f12(x: Record & { metadata: number }, k: X): T | U { +>f12 : Symbol(f12, Decl(genericRecordIntersectionAssignability.ts, 56, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 58, 13)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 58, 30)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 58, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 58, 43)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 58, 46)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 58, 50)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 58, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 58, 43)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 58, 46)) +>metadata : Symbol(metadata, Decl(genericRecordIntersectionAssignability.ts, 58, 73)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 58, 93)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 58, 30)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 58, 43)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 58, 46)) + + return x[k]; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 58, 50)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 58, 93)) +} + +function f13(x: Record & Record<`${K}`, T>, k: K): T { +>f13 : Symbol(f13, Decl(genericRecordIntersectionAssignability.ts, 60, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 62, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 62, 29)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 62, 33)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 62, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 62, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 62, 29)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 62, 75)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 62, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 62, 29)) + + return x[k]; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 62, 33)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 62, 75)) +} + +function f14(x: Record & Record<`${K}`, unknown>, k: `${K}`): number { +>f14 : Symbol(f14, Decl(genericRecordIntersectionAssignability.ts, 64, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 66, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 66, 30)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 66, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 66, 13)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 66, 77)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 66, 13)) + + return x[k]; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 66, 30)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 66, 77)) +} + +function f15(x: { [P in `${X}`]: P } & Record, k: X): X { +>f15 : Symbol(f15, Decl(genericRecordIntersectionAssignability.ts, 68, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 70, 13)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 70, 30)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 70, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 70, 44)) +>P : Symbol(P, Decl(genericRecordIntersectionAssignability.ts, 70, 50)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 70, 30)) +>P : Symbol(P, Decl(genericRecordIntersectionAssignability.ts, 70, 50)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 70, 13)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 70, 89)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 70, 30)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 70, 30)) + + return x[k]; // Error +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 70, 44)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 70, 89)) +} + +function f16(x: Record & Record<`${K}`, number>, k: K): number { +>f16 : Symbol(f16, Decl(genericRecordIntersectionAssignability.ts, 72, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 74, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 74, 31)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 74, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 74, 13)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 74, 78)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 74, 13)) + + return x[k]; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 74, 31)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 74, 78)) +} + +function f17(x: Record & Record<`${X}`, number>, k: X): number { +>f17 : Symbol(f17, Decl(genericRecordIntersectionAssignability.ts, 76, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 78, 13)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 78, 30)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 78, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 78, 44)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 78, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 78, 30)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 78, 91)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 78, 30)) + + return x[k]; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 78, 44)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 78, 91)) +} + +function f18(x: Record & { b: number }, k: X): number { +>f18 : Symbol(f18, Decl(genericRecordIntersectionAssignability.ts, 80, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 82, 13)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 82, 30)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 82, 52)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 82, 13)) +>b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 82, 82)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 82, 95)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 82, 30)) + + return x[k]; +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 82, 52)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 82, 95)) +} + +function f19(x: Record & Record & { b: T }, k: X) { +>f19 : Symbol(f19, Decl(genericRecordIntersectionAssignability.ts, 84, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 86, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 86, 31)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 86, 34)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 86, 53)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 86, 56)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 86, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 86, 77)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 86, 13)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 86, 31)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 86, 34)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 86, 53)) +>b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 86, 113)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 86, 31)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 86, 121)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 86, 56)) + + const t: T = x[k]; +>t : Symbol(t, Decl(genericRecordIntersectionAssignability.ts, 87, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 86, 31)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 86, 77)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 86, 121)) + + const tu: T & U = x[k]; // Error +>tu : Symbol(tu, Decl(genericRecordIntersectionAssignability.ts, 88, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 86, 31)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 86, 53)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 86, 77)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 86, 121)) +} + +function f20(x: Record & Record & { b: string }, k: X): number { +>f20 : Symbol(f20, Decl(genericRecordIntersectionAssignability.ts, 89, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 91, 13)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 91, 31)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 91, 50)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 91, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 91, 71)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 91, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 91, 31)) +>b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 91, 117)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 91, 130)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 91, 50)) + + return x[k]; // Error +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 91, 71)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 91, 130)) +} + +function f21(x: Record & Record, k: X) { +>f21 : Symbol(f21, Decl(genericRecordIntersectionAssignability.ts, 93, 1)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 95, 13)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 95, 31)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 95, 50)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 95, 13)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 95, 65)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(genericRecordIntersectionAssignability.ts, 95, 13)) +>a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 95, 80)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(genericRecordIntersectionAssignability.ts, 95, 31)) +>b : Symbol(b, Decl(genericRecordIntersectionAssignability.ts, 95, 108)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 95, 122)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 95, 50)) + + x[k].a; +>x[k].a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 95, 80)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 95, 65)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 95, 122)) +>a : Symbol(a, Decl(genericRecordIntersectionAssignability.ts, 95, 80)) + + x[k].b; // Error +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 95, 65)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 95, 122)) +} + +function f22(x: Record & Record, k: X) { +>f22 : Symbol(f22, Decl(genericRecordIntersectionAssignability.ts, 98, 1)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 100, 13)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 100, 30)) +>K : Symbol(K, Decl(genericRecordIntersectionAssignability.ts, 100, 13)) +>L : Symbol(L, Decl(genericRecordIntersectionAssignability.ts, 100, 43)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 100, 61)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 100, 64)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 100, 68)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 100, 30)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 100, 61)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>L : Symbol(L, Decl(genericRecordIntersectionAssignability.ts, 100, 43)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 100, 64)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 100, 99)) +>X : Symbol(X, Decl(genericRecordIntersectionAssignability.ts, 100, 30)) + + const t: T = x[k]; +>t : Symbol(t, Decl(genericRecordIntersectionAssignability.ts, 101, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 100, 61)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 100, 68)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 100, 99)) + + const tu: T & U = x[k]; // Error +>tu : Symbol(tu, Decl(genericRecordIntersectionAssignability.ts, 102, 9)) +>T : Symbol(T, Decl(genericRecordIntersectionAssignability.ts, 100, 61)) +>U : Symbol(U, Decl(genericRecordIntersectionAssignability.ts, 100, 64)) +>x : Symbol(x, Decl(genericRecordIntersectionAssignability.ts, 100, 68)) +>k : Symbol(k, Decl(genericRecordIntersectionAssignability.ts, 100, 99)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.types b/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.types new file mode 100644 index 0000000000000..78b23555672c2 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/genericRecordIntersectionAssignability.types @@ -0,0 +1,359 @@ +//// [tests/cases/compiler/genericRecordIntersectionAssignability.ts] //// + +=== genericRecordIntersectionAssignability.ts === +// https://github.com/microsoft/TypeScript/issues/64495 + +function f1(x: Record & Record): Record { +>f1 : (x: Record & Record) => Record +>x : Record & Record + + return x; // Error +>x : Record & Record +} + +function f2(x: Record & Record): Record { +>f2 : (x: Record & Record) => Record +>x : Record & Record + + return x; +>x : Record & Record +} + +function f3(x: Record & Record): Record { +>f3 : (x: Record & Record) => Record +>x : Record & Record + + return x; +>x : Record & Record +} + +function f4(x: Record & Record, k1: K1, k2: K2) { +>f4 : (x: Record & Record, k1: K1, k2: K2) => void +>x : Record & Record +>k1 : K1 +>k2 : K2 + + const t: T = x[k1]; +>t : T +>x[k1] : (Record & Record)[K1] +>x : Record & Record +>k1 : K1 + + const u: U = x[k2]; +>u : U +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 + + const tu1: T & U = x[k1]; // Error +>tu1 : T & U +>x[k1] : (Record & Record)[K1] +>x : Record & Record +>k1 : K1 + + const tu2: T & U = x[k2]; // Error +>tu2 : T & U +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 +} + +function f5(x: Record & Record, k1: K1, k2: K2) { +>f5 : (x: Record & Record, k1: K1, k2: K2) => void +>a : string +>b : string +>x : Record & Record +>k1 : K1 +>k2 : K2 + + x[k1].a; +>x[k1].a : string +>x[k1] : (Record & Record)[K1] +>x : Record & Record +>k1 : K1 +>a : string + + x[k1].b; // Error +>x[k1].b : any +>x[k1] : (Record & Record)[K1] +>x : Record & Record +>k1 : K1 +>b : any + + x[k2].a; // Error +>x[k2].a : any +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 +>a : any + + x[k2].b; +>x[k2].b : string +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 +>b : string +} + +function f6(x: Record & Record, k1: K1, k2: K2) { +>f6 : (x: Record & Record, k1: K1, k2: K2) => void +>x : Record & Record +>k1 : K1 +>k2 : K2 + + const t: T = x[k2]; +>t : T +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 + + const u: U = x[k2]; +>u : U +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 + + const tu: T & U = x[k2]; +>tu : T & U +>x[k2] : (Record & Record)[K2] +>x : Record & Record +>k2 : K2 + + const tu1: T & U = x[k1]; // Error +>tu1 : T & U +>x[k1] : (Record & Record)[K1] +>x : Record & Record +>k1 : K1 +} + +function f7(x: Record & Record & { extra: V }, k1: K1) { +>f7 : (x: Record & Record & { extra: V; }, k1: K1) => void +>x : Record & Record & { extra: V; } +>extra : V +>k1 : K1 + + const t: T = x[k1]; +>t : T +>x[k1] : (Record & Record & { extra: V; })[K1] +>x : Record & Record & { extra: V; } +>k1 : K1 + + const tu: T & U = x[k1]; // Error +>tu : T & U +>x[k1] : (Record & Record & { extra: V; })[K1] +>x : Record & Record & { extra: V; } +>k1 : K1 +} + +function f8(x: Record & Record & { [key: string]: V }, k1: K1) { +>f8 : (x: Record & Record & { [key: string]: V; }, k1: K1) => void +>x : Record & Record & { [key: string]: V; } +>key : string +>k1 : K1 + + const tv: T & V = x[k1]; +>tv : T & V +>x[k1] : (Record & Record & { [key: string]: V; })[K1] +>x : Record & Record & { [key: string]: V; } +>k1 : K1 + + const tu: T & U = x[k1]; // Error +>tu : T & U +>x[k1] : (Record & Record & { [key: string]: V; })[K1] +>x : Record & Record & { [key: string]: V; } +>k1 : K1 +} + +function f9(x: Record & Record & Record, k3: K3) { +>f9 : (x: Record & Record & Record, k3: K3) => void +>x : Record & Record & Record +>k3 : K3 + + const n: number = x[k3]; +>n : number +>x[k3] : (Record & Record & Record)[K3] +>x : Record & Record & Record +>k3 : K3 +} + +function f10(x: Record & Record & Record, k1: K1) { +>f10 : (x: Record & Record & Record, k1: K1) => void +>x : Record & Record & Record +>k1 : K1 + + const tv: T & V = x[k1]; +>tv : T & V +>x[k1] : (Record & Record & Record)[K1] +>x : Record & Record & Record +>k1 : K1 +} + +function f11(x: Record & { a: T }, k: K) { +>f11 : (x: Record & { a: T; }, k: K) => void +>x : Record & { a: T; } +>a : T +>k : K + + const t: T = x[k]; +>t : T +>x[k] : (Record & { a: T; })[K] +>x : Record & { a: T; } +>k : K + + const tu: T & U = x[k]; // Error +>tu : T & U +>x[k] : (Record & { a: T; })[K] +>x : Record & { a: T; } +>k : K +} + +function f12(x: Record & { metadata: number }, k: X): T | U { +>f12 : (x: Record & { metadata: number; }, k: X) => T | U +>x : Record & { metadata: number; } +>metadata : number +>k : X + + return x[k]; +>x[k] : (Record & { metadata: number; })[X] +>x : Record & { metadata: number; } +>k : X +} + +function f13(x: Record & Record<`${K}`, T>, k: K): T { +>f13 : (x: Record & Record<`${K}`, T>, k: K) => T +>x : Record & Record<`${K}`, T> +>k : K + + return x[k]; +>x[k] : (Record & Record<`${K}`, T>)[K] +>x : Record & Record<`${K}`, T> +>k : K +} + +function f14(x: Record & Record<`${K}`, unknown>, k: `${K}`): number { +>f14 : (x: Record & Record<`${K}`, unknown>, k: `${K}`) => number +>x : Record & Record<`${K}`, unknown> +>k : `${K}` + + return x[k]; +>x[k] : (Record & Record<`${K}`, unknown>)[`${K}`] +>x : Record & Record<`${K}`, unknown> +>k : `${K}` +} + +function f15(x: { [P in `${X}`]: P } & Record, k: X): X { +>f15 : (x: { [P in `${X}`]: P; } & Record, k: X) => X +>x : { [P in `${X}`]: P; } & Record +>k : X + + return x[k]; // Error +>x[k] : ({ [P in `${X}`]: P; } & Record)[X] +>x : { [P in `${X}`]: P; } & Record +>k : X +} + +function f16(x: Record & Record<`${K}`, number>, k: K): number { +>f16 : (x: Record & Record<`${K}`, number>, k: K) => number +>x : Record & Record<`${K}`, number> +>k : K + + return x[k]; +>x[k] : (Record & Record<`${K}`, number>)[K] +>x : Record & Record<`${K}`, number> +>k : K +} + +function f17(x: Record & Record<`${X}`, number>, k: X): number { +>f17 : (x: Record & Record<`${X}`, number>, k: X) => number +>x : Record & Record<`${X}`, number> +>k : X + + return x[k]; +>x[k] : (Record & Record<`${X}`, number>)[X] +>x : Record & Record<`${X}`, number> +>k : X +} + +function f18(x: Record & { b: number }, k: X): number { +>f18 : (x: Record & { b: number; }, k: X) => number +>x : Record<"a" | K, number> & { b: number; } +>b : number +>k : X + + return x[k]; +>x[k] : (Record<"a" | K, number> & { b: number; })[X] +>x : Record<"a" | K, number> & { b: number; } +>k : X +} + +function f19(x: Record & Record & { b: T }, k: X) { +>f19 : (x: Record & Record & { b: T; }, k: X) => void +>x : Record & Record & { b: T; } +>b : T +>k : X + + const t: T = x[k]; +>t : T +>x[k] : (Record & Record & { b: T; })[X] +>x : Record & Record & { b: T; } +>k : X + + const tu: T & U = x[k]; // Error +>tu : T & U +>x[k] : (Record & Record & { b: T; })[X] +>x : Record & Record & { b: T; } +>k : X +} + +function f20(x: Record & Record & { b: string }, k: X): number { +>f20 : (x: Record & Record & { b: string; }, k: X) => number +>x : Record & Record & { b: string; } +>b : string +>k : X + + return x[k]; // Error +>x[k] : string | number +>x : Record & Record & { b: string; } +>k : X +} + +function f21(x: Record & Record, k: X) { +>f21 : (x: Record & Record, k: X) => void +>x : Record & Record +>a : string +>b : string +>k : X + + x[k].a; +>x[k].a : string +>x[k] : (Record & Record)[X] +>x : Record & Record +>k : X +>a : string + + x[k].b; // Error +>x[k].b : any +>x[k] : (Record & Record)[X] +>x : Record & Record +>k : X +>b : any +} + +function f22(x: Record & Record, k: X) { +>f22 : (x: Record & Record, k: X) => void +>x : Record & Record +>k : X + + const t: T = x[k]; +>t : T +>x[k] : (Record & Record)[X] +>x : Record & Record +>k : X + + const tu: T & U = x[k]; // Error +>tu : T & U +>x[k] : (Record & Record)[X] +>x : Record & Record +>k : X +} + diff --git a/tsc/testdata/tests/cases/compiler/genericRecordIntersectionAssignability.ts b/tsc/testdata/tests/cases/compiler/genericRecordIntersectionAssignability.ts new file mode 100644 index 0000000000000..fbbe05bc4a40c --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/genericRecordIntersectionAssignability.ts @@ -0,0 +1,107 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/64495 + +function f1(x: Record & Record): Record { + return x; // Error +} + +function f2(x: Record & Record): Record { + return x; +} + +function f3(x: Record & Record): Record { + return x; +} + +function f4(x: Record & Record, k1: K1, k2: K2) { + const t: T = x[k1]; + const u: U = x[k2]; + const tu1: T & U = x[k1]; // Error + const tu2: T & U = x[k2]; // Error +} + +function f5(x: Record & Record, k1: K1, k2: K2) { + x[k1].a; + x[k1].b; // Error + x[k2].a; // Error + x[k2].b; +} + +function f6(x: Record & Record, k1: K1, k2: K2) { + const t: T = x[k2]; + const u: U = x[k2]; + const tu: T & U = x[k2]; + const tu1: T & U = x[k1]; // Error +} + +function f7(x: Record & Record & { extra: V }, k1: K1) { + const t: T = x[k1]; + const tu: T & U = x[k1]; // Error +} + +function f8(x: Record & Record & { [key: string]: V }, k1: K1) { + const tv: T & V = x[k1]; + const tu: T & U = x[k1]; // Error +} + +function f9(x: Record & Record & Record, k3: K3) { + const n: number = x[k3]; +} + +function f10(x: Record & Record & Record, k1: K1) { + const tv: T & V = x[k1]; +} + +function f11(x: Record & { a: T }, k: K) { + const t: T = x[k]; + const tu: T & U = x[k]; // Error +} + +function f12(x: Record & { metadata: number }, k: X): T | U { + return x[k]; +} + +function f13(x: Record & Record<`${K}`, T>, k: K): T { + return x[k]; +} + +function f14(x: Record & Record<`${K}`, unknown>, k: `${K}`): number { + return x[k]; +} + +function f15(x: { [P in `${X}`]: P } & Record, k: X): X { + return x[k]; // Error +} + +function f16(x: Record & Record<`${K}`, number>, k: K): number { + return x[k]; +} + +function f17(x: Record & Record<`${X}`, number>, k: X): number { + return x[k]; +} + +function f18(x: Record & { b: number }, k: X): number { + return x[k]; +} + +function f19(x: Record & Record & { b: T }, k: X) { + const t: T = x[k]; + const tu: T & U = x[k]; // Error +} + +function f20(x: Record & Record & { b: string }, k: X): number { + return x[k]; // Error +} + +function f21(x: Record & Record, k: X) { + x[k].a; + x[k].b; // Error +} + +function f22(x: Record & Record, k: X) { + const t: T = x[k]; + const tu: T & U = x[k]; // Error +}