Merge pull request #23645 from Microsoft/distributeKeyofUnion2

Distribute 'keyof' union types (take 2)
This commit is contained in:
Anders Hejlsberg
2018-04-24 10:09:45 -07:00
committed by GitHub
10 changed files with 594 additions and 191 deletions

View File

@@ -8268,7 +8268,8 @@ namespace ts {
}
function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type {
return type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly))) :
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly))) :
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly))) :
maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(<MappedType>type) :
type === wildcardType ? wildcardType :

View File

@@ -565,6 +565,24 @@ function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K]): void {
type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
enum Flag {
FLAG_1 = "flag_1",
FLAG_2 = "flag_2"
}
type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag>
function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) {
return record[flags[0]];
}
type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag>
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
return record[flags[0]];
}
//// [keyofAndIndexedAccess.js]
@@ -948,6 +966,17 @@ function f3(t, k, tk) {
t[key] = tk; // ok, T[K] ==> T[keyof T]
}
}
var Flag;
(function (Flag) {
Flag["FLAG_1"] = "flag_1";
Flag["FLAG_2"] = "flag_2";
})(Flag || (Flag = {}));
function getFlagsFromSimpleRecord(record, flags) {
return record[flags[0]];
}
function getFlagsFromDynamicRecord(record, flags) {
return record[flags[0]];
}
//// [keyofAndIndexedAccess.d.ts]
@@ -1212,3 +1241,20 @@ declare function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K])
declare type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T];
};
declare type DBBoolTable<K extends string> = {
[k in K]: 0 | 1;
};
declare enum Flag {
FLAG_1 = "flag_1",
FLAG_2 = "flag_2"
}
declare type SimpleDBRecord<Flag extends string> = {
staticField: number;
} & DBBoolTable<Flag>;
declare function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]): SimpleDBRecord<Flag>[Flag];
declare type DynamicDBRecord<Flag extends string> = ({
dynamicField: number;
} | {
dynamicField: string;
}) & DBBoolTable<Flag>;
declare function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]): DynamicDBRecord<Flag>[Flag];

View File

@@ -2010,3 +2010,64 @@ type Predicates<TaggedRecord> = {
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3))
}
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 17))
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 569, 40))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 17))
enum Flag {
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 569, 56))
FLAG_1 = "flag_1",
>FLAG_1 : Symbol(Flag.FLAG_1, Decl(keyofAndIndexedAccess.ts, 570, 11))
FLAG_2 = "flag_2"
>FLAG_2 : Symbol(Flag.FLAG_2, Decl(keyofAndIndexedAccess.ts, 571, 22))
}
type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag>
>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 573, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 575, 20))
>staticField : Symbol(staticField, Decl(keyofAndIndexedAccess.ts, 575, 44))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 575, 20))
function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) {
>getFlagsFromSimpleRecord : Symbol(getFlagsFromSimpleRecord, Decl(keyofAndIndexedAccess.ts, 575, 86))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 576, 55))
>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 573, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 576, 84))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34))
return record[flags[0]];
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 576, 55))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 576, 84))
}
type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag>
>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 578, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 580, 21))
>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 580, 46))
>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 580, 73))
>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 580, 21))
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
>getFlagsFromDynamicRecord : Symbol(getFlagsFromDynamicRecord, Decl(keyofAndIndexedAccess.ts, 580, 117))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35))
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 581, 56))
>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 578, 1))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 581, 86))
>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35))
return record[flags[0]];
>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 581, 56))
>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 581, 86))
}

View File

@@ -890,11 +890,11 @@ function f60<T>(source: T, target: T) {
}
function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
>f70 : (func: <T, U>(k1: keyof (T | U), k2: keyof T | keyof U) => void) => void
>func : <T, U>(k1: keyof (T | U), k2: keyof T | keyof U) => void
>f70 : (func: <T, U>(k1: keyof T & keyof U, k2: keyof T | keyof U) => void) => void
>func : <T, U>(k1: keyof T & keyof U, k2: keyof T | keyof U) => void
>T : T
>U : U
>k1 : keyof (T | U)
>k1 : keyof T & keyof U
>T : T
>U : U
>k2 : keyof T | keyof U
@@ -903,7 +903,7 @@ function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
func<{ a: any, b: any }, { a: any, c: any }>('a', 'a');
>func<{ a: any, b: any }, { a: any, c: any }>('a', 'a') : void
>func : <T, U>(k1: keyof (T | U), k2: keyof T | keyof U) => void
>func : <T, U>(k1: keyof T & keyof U, k2: keyof T | keyof U) => void
>a : any
>b : any
>a : any
@@ -913,7 +913,7 @@ function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
func<{ a: any, b: any }, { a: any, c: any }>('a', 'b');
>func<{ a: any, b: any }, { a: any, c: any }>('a', 'b') : void
>func : <T, U>(k1: keyof (T | U), k2: keyof T | keyof U) => void
>func : <T, U>(k1: keyof T & keyof U, k2: keyof T | keyof U) => void
>a : any
>b : any
>a : any
@@ -923,7 +923,7 @@ function f70(func: <T, U>(k1: keyof (T | U), k2: keyof (T & U)) => void) {
func<{ a: any, b: any }, { a: any, c: any }>('a', 'c');
>func<{ a: any, b: any }, { a: any, c: any }>('a', 'c') : void
>func : <T, U>(k1: keyof (T | U), k2: keyof T | keyof U) => void
>func : <T, U>(k1: keyof T & keyof U, k2: keyof T | keyof U) => void
>a : any
>b : any
>a : any
@@ -1097,8 +1097,8 @@ function f73(func: <T, U, K extends keyof (T & U)>(x: T, y: U, k: K) => (T & U)[
}
function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) {
>f74 : (func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]) => void
>func : <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]
>f74 : (func: <T, U, K extends keyof T & keyof U>(x: T, y: U, k: K) => (T | U)[K]) => void
>func : <T, U, K extends keyof T & keyof U>(x: T, y: U, k: K) => (T | U)[K]
>T : T
>U : U
>K : K
@@ -1117,7 +1117,7 @@ function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[
let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number
>a : number
>func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a') : number
>func : <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]
>func : <T, U, K extends keyof T & keyof U>(x: T, y: U, k: K) => (T | U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
@@ -1133,7 +1133,7 @@ function f74(func: <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[
let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean
>b : string | boolean
>func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b') : string | boolean
>func : <T, U, K extends keyof (T | U)>(x: T, y: U, k: K) => (T | U)[K]
>func : <T, U, K extends keyof T & keyof U>(x: T, y: U, k: K) => (T | U)[K]
>{ a: 1, b: "hello" } : { a: number; b: string; }
>a : number
>1 : 1
@@ -2345,3 +2345,72 @@ type Predicates<TaggedRecord> = {
>T : T
}
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
>DBBoolTable : DBBoolTable<K>
>K : K
>k : k
>K : K
enum Flag {
>Flag : Flag
FLAG_1 = "flag_1",
>FLAG_1 : Flag.FLAG_1
>"flag_1" : "flag_1"
FLAG_2 = "flag_2"
>FLAG_2 : Flag.FLAG_2
>"flag_2" : "flag_2"
}
type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag>
>SimpleDBRecord : SimpleDBRecord<Flag>
>Flag : Flag
>staticField : number
>DBBoolTable : DBBoolTable<K>
>Flag : Flag
function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) {
>getFlagsFromSimpleRecord : <Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) => SimpleDBRecord<Flag>[Flag]
>Flag : Flag
>record : SimpleDBRecord<Flag>
>SimpleDBRecord : SimpleDBRecord<Flag>
>Flag : Flag
>flags : Flag[]
>Flag : Flag
return record[flags[0]];
>record[flags[0]] : SimpleDBRecord<Flag>[Flag]
>record : SimpleDBRecord<Flag>
>flags[0] : Flag
>flags : Flag[]
>0 : 0
}
type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag>
>DynamicDBRecord : DynamicDBRecord<Flag>
>Flag : Flag
>dynamicField : number
>dynamicField : string
>DBBoolTable : DBBoolTable<K>
>Flag : Flag
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
>getFlagsFromDynamicRecord : <Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) => DynamicDBRecord<Flag>[Flag]
>Flag : Flag
>record : DynamicDBRecord<Flag>
>DynamicDBRecord : DynamicDBRecord<Flag>
>Flag : Flag
>flags : Flag[]
>Flag : Flag
return record[flags[0]];
>record[flags[0]] : DynamicDBRecord<Flag>[Flag]
>record : DynamicDBRecord<Flag>
>flags[0] : Flag
>flags : Flag[]
>0 : 0
}

View File

@@ -22,33 +22,44 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(64,33): error
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(66,24): error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(67,24): error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'.
Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(72,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error TS2322: Type 'T | U' is not assignable to type 'T & U'.
Type 'T' is not assignable to type 'T & U'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'.
Type 'keyof T' is not assignable to type 'keyof (T | U)'.
Type 'string | number | symbol' is not assignable to type 'keyof (T | U)'.
Type 'string' is not assignable to type 'keyof (T | U)'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'Extract<keyof T, string>' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(73,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(74,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(82,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
Type 'string | number | symbol' is not assignable to type 'keyof T & keyof U'.
Type 'string' is not assignable to type 'keyof T & keyof U'.
Type 'string' is not assignable to type 'keyof T'.
Type 'keyof T' is not assignable to type 'keyof U'.
Type 'string | number | symbol' is not assignable to type 'keyof U'.
Type 'string' is not assignable to type 'keyof U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(83,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(87,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
Type 'keyof T' is not assignable to type 'keyof U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract<keyof T, string>' is not assignable to type 'K'.
Type 'string & keyof T' is not assignable to type 'K'.
Type 'string' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[Extract<keyof T, string>]' is not assignable to type 'T[K]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract<keyof T, string>]' is not assignable to type 'T[K]'.
Type 'Extract<keyof T, string>' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(91,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(108,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(94,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(111,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(97,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(114,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'.
Type 'K' is not assignable to type 'J'.
Type 'Extract<keyof T, string>' is not assignable to type 'J'.
Type 'string & keyof T' is not assignable to type 'J'.
Type 'string' is not assignable to type 'J'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
Type 'T' is not assignable to type 'U'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (31 errors) ====
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (34 errors) ====
class Shape {
name: string;
width: number;
@@ -164,26 +175,57 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error
!!! error TS2345: Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'.
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
o1[k1];
o1[k2]; // Error
~~~~~~
function f20<T, U>(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) {
x[k1];
x[k2];
x[k3]; // Error
~~~~~
!!! error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'.
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
x[k4]; // Error
~~~~~
!!! error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'.
y[k1];
y[k2];
y[k3];
y[k4];
k1 = k2;
k1 = k3; // Error
~~
!!! error TS2322: Type 'T | U' 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'.
k1 = k2; // Error
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'string' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'string' is not assignable to type 'keyof T'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'.
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof U'.
!!! error TS2322: Type 'string' is not assignable to type 'keyof U'.
k1 = k4; // Error
~~
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof (T | U)'.
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof (T | U)'.
!!! error TS2322: Type 'string' is not assignable to type 'keyof (T | U)'.
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'.
k2 = k1;
k2 = k3; // Error
~~
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'.
k2 = k4; // Error
~~
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'.
k3 = k1;
k3 = k2;
k3 = k4;
k4 = k1;
k4 = k2;
k4 = k3;
}
// Repro from #17166

View File

@@ -68,15 +68,32 @@ function f10(shape: Shape) {
setProperty(shape, cond ? "name" : "size", 10); // Error
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
o1[k1];
o1[k2]; // Error
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
k1 = k2; // Error
function f20<T, U>(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) {
x[k1];
x[k2];
x[k3]; // Error
x[k4]; // Error
y[k1];
y[k2];
y[k3];
y[k4];
k1 = k2;
k1 = k3; // Error
k1 = k4; // Error
k2 = k1;
k2 = k3; // Error
k2 = k4; // Error
k3 = k1;
k3 = k2;
k3 = k4;
k4 = k1;
k4 = k2;
k4 = k3;
}
// Repro from #17166
@@ -122,15 +139,27 @@ function f10(shape) {
setProperty(shape, "size", 10); // Error
setProperty(shape, cond ? "name" : "size", 10); // Error
}
function f20(k1, k2, o1, o2) {
o1[k1];
o1[k2]; // Error
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
k1 = k2; // Error
function f20(x, y, k1, k2, k3, k4) {
x[k1];
x[k2];
x[k3]; // Error
x[k4]; // Error
y[k1];
y[k2];
y[k3];
y[k4];
k1 = k2;
k1 = k3; // Error
k1 = k4; // Error
k2 = k1;
k2 = k3; // Error
k2 = k4; // Error
k3 = k1;
k3 = k2;
k3 = k4;
k4 = k1;
k4 = k2;
k4 = k3;
}
// Repro from #17166
function f3(t, k, tk, u, j, uk, tj, uj) {

View File

@@ -219,142 +219,196 @@ function f10(shape: Shape) {
>cond : Symbol(cond, Decl(keyofAndIndexedAccessErrors.ts, 50, 11))
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
function f20<T, U>(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) {
>f20 : Symbol(f20, Decl(keyofAndIndexedAccessErrors.ts, 67, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37))
>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
>o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
>o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15))
o1[k1];
>o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
x[k1];
>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
o1[k2]; // Error
>o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37))
x[k2];
>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
o2[k1];
>o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
x[k3]; // Error
>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
o2[k2];
>o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37))
x[k4]; // Error
>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
o1 = o2;
>o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56))
>o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67))
y[k1];
>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
o2 = o1; // Error
>o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67))
>o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56))
y[k2];
>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
k1 = k2; // Error
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37))
y[k3];
>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28))
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
y[k4];
>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28))
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
k1 = k2;
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
k1 = k3; // Error
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
k1 = k4; // Error
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
k2 = k1;
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
k2 = k3; // Error
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
k2 = k4; // Error
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
k3 = k1;
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
k3 = k2;
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
k3 = k4;
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
k4 = k1;
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38))
k4 = k2;
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57))
k4 = k3;
>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99))
>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80))
}
// Repro from #17166
function f3<T, K extends Extract<keyof T, string>, U extends T, J extends K>(
>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 95, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14))
>Extract : Symbol(Extract, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14))
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 82, 25))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50))
>j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 82, 31))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 99, 9))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14))
>u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 99, 25))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50))
>j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 99, 31))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 99, 37))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63))
for (let key in t) {
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77))
key = k // ok, K ==> keyof T
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 99, 9))
k = key // error, keyof T =/=> K
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 99, 9))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12))
t[key] = tk; // ok, T[K] ==> T[keyof T]
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
tk = t[key]; // error, T[keyof T] =/=> T[K]
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12))
}
tk = uk;
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 99, 37))
uk = tk; // error
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 99, 37))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
tj = uj;
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57))
uj = tj; // error
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47))
tk = tj;
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47))
tj = tk; // error
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
tk = uj;
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57))
uj = tk; // error
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15))
}

View File

@@ -34,19 +34,19 @@ type T02 = keyof keyof Object;
>Object : Object
type T03 = keyof keyof keyof Object;
>T03 : "toString" | "toLocaleString" | "valueOf"
>T03 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number)
>Object : Object
type T04 = keyof keyof keyof keyof Object;
>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr"
>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number)
>Object : Object
type T05 = keyof keyof keyof keyof keyof Object;
>T05 : "toString" | "toLocaleString" | "valueOf"
>T05 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number)
>Object : Object
type T06 = keyof keyof keyof keyof keyof keyof Object;
>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr"
>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number)
>Object : Object
type T10 = Shape["name"];
@@ -242,62 +242,128 @@ function f10(shape: Shape) {
>10 : 10
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
>f20 : <T, U>(k1: keyof (T | U), k2: keyof T | keyof U, o1: T | U, o2: T & U) => void
function f20<T, U>(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) {
>f20 : <T, U>(x: T | U, y: T & U, k1: keyof T & keyof U, k2: keyof T & keyof U, k3: keyof T | keyof U, k4: keyof T | keyof U) => void
>T : T
>U : U
>k1 : keyof (T | U)
>x : T | U
>T : T
>U : U
>k2 : keyof T | keyof U
>y : T & U
>T : T
>U : U
>o1 : T | U
>k1 : keyof T & keyof U
>T : T
>U : U
>o2 : T & U
>k2 : keyof T & keyof U
>T : T
>U : U
>k3 : keyof T | keyof U
>T : T
>U : U
>k4 : keyof T | keyof U
>T : T
>U : U
o1[k1];
>o1[k1] : (T | U)[keyof (T | U)]
>o1 : T | U
>k1 : keyof (T | U)
x[k1];
>x[k1] : (T | U)[keyof T & keyof U]
>x : T | U
>k1 : keyof T & keyof U
o1[k2]; // Error
>o1[k2] : (T | U)[keyof T | keyof U]
>o1 : T | U
>k2 : keyof T | keyof U
x[k2];
>x[k2] : (T | U)[keyof T & keyof U]
>x : T | U
>k2 : keyof T & keyof U
o2[k1];
>o2[k1] : (T & U)[keyof (T | U)]
>o2 : T & U
>k1 : keyof (T | U)
x[k3]; // Error
>x[k3] : (T | U)[keyof T | keyof U]
>x : T | U
>k3 : keyof T | keyof U
o2[k2];
>o2[k2] : (T & U)[keyof T | keyof U]
>o2 : T & U
>k2 : keyof T | keyof U
x[k4]; // Error
>x[k4] : (T | U)[keyof T | keyof U]
>x : T | U
>k4 : keyof T | keyof U
o1 = o2;
>o1 = o2 : T & U
>o1 : T | U
>o2 : T & U
y[k1];
>y[k1] : (T & U)[keyof T & keyof U]
>y : T & U
>k1 : keyof T & keyof U
o2 = o1; // Error
>o2 = o1 : T | U
>o2 : T & U
>o1 : T | U
y[k2];
>y[k2] : (T & U)[keyof T & keyof U]
>y : T & U
>k2 : keyof T & keyof U
k1 = k2; // Error
>k1 = k2 : keyof T | keyof U
>k1 : keyof (T | U)
>k2 : keyof T | keyof U
y[k3];
>y[k3] : (T & U)[keyof T | keyof U]
>y : T & U
>k3 : keyof T | keyof U
y[k4];
>y[k4] : (T & U)[keyof T | keyof U]
>y : T & U
>k4 : keyof T | keyof U
k1 = k2;
>k1 = k2 : keyof T & keyof U
>k1 : keyof T & keyof U
>k2 : keyof T & keyof U
k1 = k3; // Error
>k1 = k3 : keyof T | keyof U
>k1 : keyof T & keyof U
>k3 : keyof T | keyof U
k1 = k4; // Error
>k1 = k4 : keyof T | keyof U
>k1 : keyof T & keyof U
>k4 : keyof T | keyof U
k2 = k1;
>k2 = k1 : keyof (T | U)
>k2 : keyof T | keyof U
>k1 : keyof (T | U)
>k2 = k1 : keyof T & keyof U
>k2 : keyof T & keyof U
>k1 : keyof T & keyof U
k2 = k3; // Error
>k2 = k3 : keyof T | keyof U
>k2 : keyof T & keyof U
>k3 : keyof T | keyof U
k2 = k4; // Error
>k2 = k4 : keyof T | keyof U
>k2 : keyof T & keyof U
>k4 : keyof T | keyof U
k3 = k1;
>k3 = k1 : keyof T & keyof U
>k3 : keyof T | keyof U
>k1 : keyof T & keyof U
k3 = k2;
>k3 = k2 : keyof T & keyof U
>k3 : keyof T | keyof U
>k2 : keyof T & keyof U
k3 = k4;
>k3 = k4 : keyof T | keyof U
>k3 : keyof T | keyof U
>k4 : keyof T | keyof U
k4 = k1;
>k4 = k1 : keyof T & keyof U
>k4 : keyof T | keyof U
>k1 : keyof T & keyof U
k4 = k2;
>k4 = k2 : keyof T & keyof U
>k4 : keyof T | keyof U
>k2 : keyof T & keyof U
k4 = k3;
>k4 = k3 : keyof T | keyof U
>k4 : keyof T | keyof U
>k3 : keyof T | keyof U
}
// Repro from #17166

View File

@@ -567,3 +567,21 @@ function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K]): void {
type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
enum Flag {
FLAG_1 = "flag_1",
FLAG_2 = "flag_2"
}
type SimpleDBRecord<Flag extends string> = { staticField: number } & DBBoolTable<Flag>
function getFlagsFromSimpleRecord<Flag extends string>(record: SimpleDBRecord<Flag>, flags: Flag[]) {
return record[flags[0]];
}
type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable<Flag>
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
return record[flags[0]];
}

View File

@@ -67,15 +67,32 @@ function f10(shape: Shape) {
setProperty(shape, cond ? "name" : "size", 10); // Error
}
function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
o1[k1];
o1[k2]; // Error
o2[k1];
o2[k2];
o1 = o2;
o2 = o1; // Error
k1 = k2; // Error
function f20<T, U>(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) {
x[k1];
x[k2];
x[k3]; // Error
x[k4]; // Error
y[k1];
y[k2];
y[k3];
y[k4];
k1 = k2;
k1 = k3; // Error
k1 = k4; // Error
k2 = k1;
k2 = k3; // Error
k2 = k4; // Error
k3 = k1;
k3 = k2;
k3 = k4;
k4 = k1;
k4 = k2;
k4 = k3;
}
// Repro from #17166