From 09590bc041c261ba0ccb3d9321fb2499765ec8b6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 20:57:11 -0700 Subject: [PATCH 1/8] Transform 'keyof (A | B)' to 'keyof A & keyof B' --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75f8715fca7..b94d14d58a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8268,7 +8268,8 @@ namespace ts { } function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type { - return type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : + return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly))) : + type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : From 2911d5d7d75d98329192328a24d360c14719e6a7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 20:57:20 -0700 Subject: [PATCH 2/8] Accept new baselines --- .../reference/keyofAndIndexedAccess.types | 20 +++++++------- .../keyofAndIndexedAccessErrors.errors.txt | 24 +++++++++++------ .../keyofAndIndexedAccessErrors.types | 26 +++++++++---------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 4e41b58e664..1df9dd4e42b 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -890,11 +890,11 @@ function f60(source: T, target: T) { } function f70(func: (k1: keyof (T | U), k2: keyof (T & U)) => void) { ->f70 : (func: (k1: keyof (T | U), k2: keyof T | keyof U) => void) => void ->func : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>f70 : (func: (k1: keyof T & keyof U, k2: keyof T | keyof U) => void) => void +>func : (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: (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 : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >a : any >b : any >a : any @@ -913,7 +913,7 @@ function f70(func: (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 : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >a : any >b : any >a : any @@ -923,7 +923,7 @@ function f70(func: (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 : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >a : any >b : any >a : any @@ -1097,8 +1097,8 @@ function f73(func: (x: T, y: U, k: K) => (T & U)[ } function f74(func: (x: T, y: U, k: K) => (T | U)[K]) { ->f74 : (func: (x: T, y: U, k: K) => (T | U)[K]) => void ->func : (x: T, y: U, k: K) => (T | U)[K] +>f74 : (func: (x: T, y: U, k: K) => (T | U)[K]) => void +>func : (x: T, y: U, k: K) => (T | U)[K] >T : T >U : U >K : K @@ -1117,7 +1117,7 @@ function f74(func: (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 : (x: T, y: U, k: K) => (T | U)[K] +>func : (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: (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 : (x: T, y: U, k: K) => (T | U)[K] +>func : (x: T, y: U, k: K) => (T | U)[K] >{ a: 1, b: "hello" } : { a: number; b: string; } >a : number >1 : 1 diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index f9bb63c43b1..37af61dd943 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -26,10 +26,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(72,5): error 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(77,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(86,9): error TS2322: Type 'Extract' is not assignable to type 'K'. Type 'string & keyof T' is not assignable to type 'K'. Type 'string' is not assignable to type 'K'. @@ -179,10 +183,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error !!! 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 | 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 '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'. k2 = k1; } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 2f50ef5c53c..6f79f6cf64a 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -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"]; @@ -243,10 +243,10 @@ function f10(shape: Shape) { } function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { ->f20 : (k1: keyof (T | U), k2: keyof T | keyof U, o1: T | U, o2: T & U) => void +>f20 : (k1: keyof T & keyof U, k2: keyof T | keyof U, o1: T | U, o2: T & U) => void >T : T >U : U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U >T : T >U : U >k2 : keyof T | keyof U @@ -260,9 +260,9 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >U : U o1[k1]; ->o1[k1] : (T | U)[keyof (T | U)] +>o1[k1] : (T | U)[keyof T & keyof U] >o1 : T | U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U o1[k2]; // Error >o1[k2] : (T | U)[keyof T | keyof U] @@ -270,9 +270,9 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : keyof T | keyof U o2[k1]; ->o2[k1] : (T & U)[keyof (T | U)] +>o2[k1] : (T & U)[keyof T & keyof U] >o2 : T & U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U o2[k2]; >o2[k2] : (T & U)[keyof T | keyof U] @@ -291,13 +291,13 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { k1 = k2; // Error >k1 = k2 : keyof T | keyof U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U >k2 : keyof T | keyof U k2 = k1; ->k2 = k1 : keyof (T | U) +>k2 = k1 : keyof T & keyof U >k2 : keyof T | keyof U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U } // Repro from #17166 From 7befd35009742d47c1f5e7a37d88c2b721745a2c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 21:09:49 -0700 Subject: [PATCH 3/8] Add tests --- .../types/keyof/keyofAndIndexedAccess.ts | 18 ++++++++++ .../keyof/keyofAndIndexedAccessErrors.ts | 33 ++++++++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index e0c1f544d97..03d4ae01ea1 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -567,3 +567,21 @@ function f3>(t: T, k: K, tk: T[K]): void { type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] } + +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" +} + +type SimpleDBRecord = { staticField: number } & DBBoolTable +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { + return record[flags[0]]; +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { + return record[flags[0]]; +} diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index 618f483655e..bb2b9d95117 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -67,15 +67,32 @@ function f10(shape: Shape) { setProperty(shape, cond ? "name" : "size", 10); // Error } -function f20(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(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 From f0c3291976c3d1fd389ab37c6cb5433a2b72494f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 21:09:56 -0700 Subject: [PATCH 4/8] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 46 ++++ .../reference/keyofAndIndexedAccess.symbols | 61 +++++ .../reference/keyofAndIndexedAccess.types | 69 ++++++ .../keyofAndIndexedAccessErrors.errors.txt | 84 +++++-- .../reference/keyofAndIndexedAccessErrors.js | 61 +++-- .../keyofAndIndexedAccessErrors.symbols | 222 +++++++++++------- .../keyofAndIndexedAccessErrors.types | 128 +++++++--- 7 files changed, 515 insertions(+), 156 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 422cef5a574..f0af336563c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -565,6 +565,24 @@ function f3>(t: T, k: K, tk: T[K]): void { type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] } + +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" +} + +type SimpleDBRecord = { staticField: number } & DBBoolTable +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { + return record[flags[0]]; +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +function getFlagsFromDynamicRecord(record: DynamicDBRecord, 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: T, k: K, tk: T[K]) declare type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]; }; +declare type DBBoolTable = { + [k in K]: 0 | 1; +}; +declare enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" +} +declare type SimpleDBRecord = { + staticField: number; +} & DBBoolTable; +declare function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]): SimpleDBRecord[Flag]; +declare type DynamicDBRecord = ({ + dynamicField: number; +} | { + dynamicField: string; +}) & DBBoolTable; +declare function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]): DynamicDBRecord[Flag]; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index b1206a49388..27c7128e42d 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -2010,3 +2010,64 @@ type Predicates = { >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3)) } +// Repro from #23618 + +type DBBoolTable = { [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 = { staticField: number } & DBBoolTable +>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(record: SimpleDBRecord, 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 = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +>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(record: DynamicDBRecord, 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)) +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 1df9dd4e42b..de35c620d33 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2345,3 +2345,72 @@ type Predicates = { >T : T } +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +>DBBoolTable : DBBoolTable +>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 = { staticField: number } & DBBoolTable +>SimpleDBRecord : SimpleDBRecord +>Flag : Flag +>staticField : number +>DBBoolTable : DBBoolTable +>Flag : Flag + +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { +>getFlagsFromSimpleRecord : (record: SimpleDBRecord, flags: Flag[]) => SimpleDBRecord[Flag] +>Flag : Flag +>record : SimpleDBRecord +>SimpleDBRecord : SimpleDBRecord +>Flag : Flag +>flags : Flag[] +>Flag : Flag + + return record[flags[0]]; +>record[flags[0]] : SimpleDBRecord[Flag] +>record : SimpleDBRecord +>flags[0] : Flag +>flags : Flag[] +>0 : 0 +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +>DynamicDBRecord : DynamicDBRecord +>Flag : Flag +>dynamicField : number +>dynamicField : string +>DBBoolTable : DBBoolTable +>Flag : Flag + +function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { +>getFlagsFromDynamicRecord : (record: DynamicDBRecord, flags: Flag[]) => DynamicDBRecord[Flag] +>Flag : Flag +>record : DynamicDBRecord +>DynamicDBRecord : DynamicDBRecord +>Flag : Flag +>flags : Flag[] +>Flag : Flag + + return record[flags[0]]; +>record[flags[0]] : DynamicDBRecord[Flag] +>record : DynamicDBRecord +>flags[0] : Flag +>flags : Flag[] +>0 : 0 +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 37af61dd943..bbd4685a492 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -22,11 +22,9 @@ 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 & keyof U'. +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'. @@ -34,25 +32,34 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error 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(86,9): error TS2322: Type 'Extract' is not assignable to type 'K'. +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' 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]' is not assignable to type 'T[K]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. Type 'Extract' 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' 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; @@ -168,20 +175,23 @@ 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(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { - o1[k1]; - o1[k2]; // Error - ~~~~~~ + function f20(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 - ~~ -!!! 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 + 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 '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'. @@ -191,7 +201,31 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error !!! 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 & 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 diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index 0f026d5d2e5..c64f4df5331 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -68,15 +68,32 @@ function f10(shape: Shape) { setProperty(shape, cond ? "name" : "size", 10); // Error } -function f20(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(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) { diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index d062677fa02..bb86bf68bee 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -219,142 +219,196 @@ function f10(shape: Shape) { >cond : Symbol(cond, Decl(keyofAndIndexedAccessErrors.ts, 50, 11)) } -function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { +function f20(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, 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)) } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 6f79f6cf64a..6a474c18107 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -242,62 +242,128 @@ function f10(shape: Shape) { >10 : 10 } -function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { ->f20 : (k1: keyof T & keyof U, k2: keyof T | keyof U, o1: T | U, o2: T & U) => void +function f20(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 : (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 +>x : T | U +>T : T +>U : U +>y : T & U >T : T >U : U >k1 : keyof T & keyof U >T : T >U : U ->k2 : keyof T | keyof U +>k2 : keyof T & keyof U >T : T >U : U ->o1 : T | U +>k3 : keyof T | keyof U >T : T >U : U ->o2 : T & U +>k4 : keyof T | keyof U >T : T >U : U - o1[k1]; ->o1[k1] : (T | U)[keyof T & keyof U] ->o1 : 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 & keyof U] ->o2 : T & U + x[k3]; // Error +>x[k3] : (T | U)[keyof T | keyof U] +>x : T | U +>k3 : keyof T | keyof U + + x[k4]; // Error +>x[k4] : (T | U)[keyof T | keyof U] +>x : T | U +>k4 : keyof T | keyof U + + y[k1]; +>y[k1] : (T & U)[keyof T & keyof U] +>y : T & U >k1 : keyof T & keyof U - o2[k2]; ->o2[k2] : (T & U)[keyof T | keyof U] ->o2 : T & U ->k2 : keyof T | keyof U + y[k2]; +>y[k2] : (T & U)[keyof T & keyof U] +>y : T & U +>k2 : keyof T & keyof U - o1 = o2; ->o1 = o2 : T & U ->o1 : T | U ->o2 : T & U + y[k3]; +>y[k3] : (T & U)[keyof T | keyof U] +>y : T & U +>k3 : keyof T | keyof U - o2 = o1; // Error ->o2 = o1 : T | U ->o2 : T & U ->o1 : T | U + y[k4]; +>y[k4] : (T & U)[keyof T | keyof U] +>y : T & U +>k4 : keyof T | keyof U - k1 = k2; // Error ->k1 = k2 : keyof T | keyof U + k1 = k2; +>k1 = k2 : keyof T & keyof U >k1 : keyof T & keyof U ->k2 : 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 & keyof U ->k2 : 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 From eca17ac2434f94979960dfa30bad99ef62ab03db Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 24 Apr 2018 08:54:14 -0700 Subject: [PATCH 5/8] Support import fix even when the error is that a type is used as a value (#23655) --- src/services/codefixes/importFixes.ts | 3 ++- .../fourslash/importNameCodeFix_typeUsedAsValue.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 5a10f2f48a7..26fa45d1e53 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -7,7 +7,8 @@ namespace ts.codefix { Diagnostics.Cannot_find_name_0.code, Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, Diagnostics.Cannot_find_namespace_0.code, - Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code + Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code, + Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here.code, ], getCodeActions: getImportCodeActions, // TODO: GH#20315 diff --git a/tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts b/tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts new file mode 100644 index 00000000000..ec0fa115d0b --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts @@ -0,0 +1,14 @@ +/// + +// @Filename: /a.ts +////export class ReadonlyArray {} + +// @Filename: /b.ts +////[|new ReadonlyArray();|] + +goTo.file("/b.ts"); +verify.importFixAtPosition([ +`import { ReadonlyArray } from "./a"; + +new ReadonlyArray();`, +]); From 969aa45ea539cb2e9ab217bf1606a297c0e71190 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 24 Apr 2018 08:54:42 -0700 Subject: [PATCH 6/8] Improve error message for unused type (#23633) --- src/compiler/checker.ts | 3 ++- src/compiler/diagnosticMessages.json | 5 +++++ src/services/codefixes/fixUnusedIdentifier.ts | 1 + .../noUnusedLocals_selfReference.errors.txt | 16 +++++++-------- .../unusedClassesinModule1.errors.txt | 4 ++-- .../unusedClassesinNamespace1.errors.txt | 4 ++-- .../unusedClassesinNamespace2.errors.txt | 4 ++-- .../unusedClassesinNamespace4.errors.txt | 4 ++-- .../unusedClassesinNamespace5.errors.txt | 4 ++-- .../unusedIdentifiersConsolidated1.errors.txt | 20 +++++++++---------- .../unusedInterfaceinNamespace1.errors.txt | 4 ++-- .../unusedInterfaceinNamespace2.errors.txt | 4 ++-- .../unusedInterfaceinNamespace3.errors.txt | 4 ++-- .../unusedLocalsAndParameters.errors.txt | 4 ++-- ...LocalsAndParametersTypeAliases2.errors.txt | 8 ++++---- 15 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75f8715fca7..da2d83e4d18 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22183,7 +22183,8 @@ namespace ts { } if (!isRemovedPropertyFromObjectSpread(node.kind === SyntaxKind.Identifier ? node.parent : node)) { - addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, Diagnostics._0_is_declared_but_its_value_is_never_read, name)); + const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read; + addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, message, name)); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2bb6d4bec61..2c376da7bc9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3530,6 +3530,11 @@ "category": "Message", "code": 6195 }, + "'{0}' is declared but never used.": { + "category": "Error", + "code": 6196, + "reportsUnnecessary": true + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index a37435cd109..fd360c73ea1 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -5,6 +5,7 @@ namespace ts.codefix { const fixIdDelete = "unusedIdentifier_delete"; const errorCodes = [ Diagnostics._0_is_declared_but_its_value_is_never_read.code, + Diagnostics._0_is_declared_but_never_used.code, Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code, Diagnostics.All_imports_in_import_declaration_are_unused.code, ]; diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt index 4202a580f84..ff2291c84d6 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt @@ -1,9 +1,9 @@ tests/cases/compiler/noUnusedLocals_selfReference.ts(3,1): error TS6133: 'f' is declared but its value is never read. tests/cases/compiler/noUnusedLocals_selfReference.ts(5,5): error TS6133: 'g' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(9,1): error TS6133: 'C' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(12,1): error TS6133: 'E' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(13,1): error TS6133: 'I' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(14,1): error TS6133: 'T' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(9,1): error TS6196: 'C' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(12,1): error TS6196: 'E' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(13,1): error TS6196: 'I' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(14,1): error TS6196: 'T' is declared but never used. tests/cases/compiler/noUnusedLocals_selfReference.ts(15,1): error TS6133: 'N' is declared but its value is never read. tests/cases/compiler/noUnusedLocals_selfReference.ts(22,19): error TS6133: 'm' is declared but its value is never read. @@ -23,18 +23,18 @@ tests/cases/compiler/noUnusedLocals_selfReference.ts(22,19): error TS6133: 'm' i } class C { ~~~~~~~ -!!! error TS6133: 'C' is declared but its value is never read. +!!! error TS6196: 'C' is declared but never used. m() { C; } } enum E { A = 0, B = E.A } ~~~~~~ -!!! error TS6133: 'E' is declared but its value is never read. +!!! error TS6196: 'E' is declared but never used. interface I { x: I }; ~~~~~~~~~~~ -!!! error TS6133: 'I' is declared but its value is never read. +!!! error TS6196: 'I' is declared but never used. type T = { x: T }; ~~~~~~ -!!! error TS6133: 'T' is declared but its value is never read. +!!! error TS6196: 'T' is declared but never used. namespace N { N; } ~~~~~~~~~~~ !!! error TS6133: 'N' is declared but its value is never read. diff --git a/tests/baselines/reference/unusedClassesinModule1.errors.txt b/tests/baselines/reference/unusedClassesinModule1.errors.txt index 12b82ee97b6..488c434c537 100644 --- a/tests/baselines/reference/unusedClassesinModule1.errors.txt +++ b/tests/baselines/reference/unusedClassesinModule1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedClassesinModule1.ts(2,5): error TS6133: 'Calculator' is declared but its value is never read. +tests/cases/compiler/unusedClassesinModule1.ts(2,5): error TS6196: 'Calculator' is declared but never used. ==== tests/cases/compiler/unusedClassesinModule1.ts (1 errors) ==== module A { class Calculator { ~~~~~~~~~~~~~~~~ -!!! error TS6133: 'Calculator' is declared but its value is never read. +!!! error TS6196: 'Calculator' is declared but never used. public handelChar() { } } diff --git a/tests/baselines/reference/unusedClassesinNamespace1.errors.txt b/tests/baselines/reference/unusedClassesinNamespace1.errors.txt index 4d4f26dde7b..44050f75b54 100644 --- a/tests/baselines/reference/unusedClassesinNamespace1.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedClassesinNamespace1.ts(2,5): error TS6133: 'c1' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace1.ts(2,5): error TS6196: 'c1' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace1.ts (1 errors) ==== namespace Validation { class c1 { ~~~~~~~~ -!!! error TS6133: 'c1' is declared but its value is never read. +!!! error TS6196: 'c1' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedClassesinNamespace2.errors.txt b/tests/baselines/reference/unusedClassesinNamespace2.errors.txt index c98aeb28369..6c6f5f815b6 100644 --- a/tests/baselines/reference/unusedClassesinNamespace2.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedClassesinNamespace2.ts(2,5): error TS6133: 'c1' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace2.ts(2,5): error TS6196: 'c1' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace2.ts (1 errors) ==== namespace Validation { class c1 { ~~~~~~~~ -!!! error TS6133: 'c1' is declared but its value is never read. +!!! error TS6196: 'c1' is declared but never used. } diff --git a/tests/baselines/reference/unusedClassesinNamespace4.errors.txt b/tests/baselines/reference/unusedClassesinNamespace4.errors.txt index 7545f0e2dde..209654569c9 100644 --- a/tests/baselines/reference/unusedClassesinNamespace4.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6133: 'c3' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6196: 'c3' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace4.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6133: 'c3' is d class c3 extends c1 { ~~~~~~~~ -!!! error TS6133: 'c3' is declared but its value is never read. +!!! error TS6196: 'c3' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedClassesinNamespace5.errors.txt b/tests/baselines/reference/unusedClassesinNamespace5.errors.txt index 3512a1634c5..58cfa661603 100644 --- a/tests/baselines/reference/unusedClassesinNamespace5.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6133: 'c3' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6196: 'c3' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace5.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6133: 'c3' is d class c3 { ~~~~~~~~ -!!! error TS6133: 'c3' is declared but its value is never read. +!!! error TS6196: 'c3' is declared but never used. public x: c1; } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt b/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt index 7d3dcf34830..3ddd1f12b1b 100644 --- a/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt +++ b/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt @@ -10,11 +10,11 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(17,13): error TS6133: 'un tests/cases/compiler/unusedIdentifiersConsolidated1.ts(24,13): error TS6133: 'unUsedPrivateFunction' is declared but its value is never read. tests/cases/compiler/unusedIdentifiersConsolidated1.ts(37,11): error TS6133: 'numberRegexp' is declared but its value is never read. tests/cases/compiler/unusedIdentifiersConsolidated1.ts(44,17): error TS6133: 'unUsedPrivateFunction' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(57,5): error TS6133: 'usedLocallyInterface2' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(64,5): error TS6133: 'dummy' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(67,5): error TS6133: 'unusedInterface' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(79,5): error TS6133: 'class3' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'interface5' is declared but its value is never read. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(57,5): error TS6196: 'usedLocallyInterface2' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(64,5): error TS6196: 'dummy' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(67,5): error TS6196: 'unusedInterface' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(79,5): error TS6196: 'class3' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'interface5' is declared but never used. ==== tests/cases/compiler/unusedIdentifiersConsolidated1.ts (17 errors) ==== @@ -100,7 +100,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int interface usedLocallyInterface2 { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS6133: 'usedLocallyInterface2' is declared but its value is never read. +!!! error TS6196: 'usedLocallyInterface2' is declared but never used. someFunction(s1: string): void; } @@ -109,12 +109,12 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int class dummy implements usedLocallyInterface { ~~~~~~~~~~~ -!!! error TS6133: 'dummy' is declared but its value is never read. +!!! error TS6196: 'dummy' is declared but never used. } interface unusedInterface { ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS6133: 'unusedInterface' is declared but its value is never read. +!!! error TS6196: 'unusedInterface' is declared but never used. } } @@ -128,7 +128,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int class class3 { ~~~~~~~~~~~~ -!!! error TS6133: 'class3' is declared but its value is never read. +!!! error TS6196: 'class3' is declared but never used. } export class class4 { @@ -150,6 +150,6 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int interface interface5 { ~~~~~~~~~~~~~~~~~~~~ -!!! error TS6133: 'interface5' is declared but its value is never read. +!!! error TS6196: 'interface5' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt index e5e01491727..0fe77374c4d 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedInterfaceinNamespace1.ts(2,5): error TS6133: 'i1' is declared but its value is never read. +tests/cases/compiler/unusedInterfaceinNamespace1.ts(2,5): error TS6196: 'i1' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace1.ts (1 errors) ==== namespace Validation { interface i1 { ~~~~~~~~~~~~ -!!! error TS6133: 'i1' is declared but its value is never read. +!!! error TS6196: 'i1' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt index 3839b63f507..40e224358af 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedInterfaceinNamespace2.ts(2,5): error TS6133: 'i1' is declared but its value is never read. +tests/cases/compiler/unusedInterfaceinNamespace2.ts(2,5): error TS6196: 'i1' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace2.ts (1 errors) ==== namespace Validation { interface i1 { ~~~~~~~~~~~~ -!!! error TS6133: 'i1' is declared but its value is never read. +!!! error TS6196: 'i1' is declared but never used. } diff --git a/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt index 76d32cdf583..206dd51c3e5 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6133: 'i3' is declared but its value is never read. +tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6196: 'i3' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace3.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6133: 'i3' is interface i3 extends i1 { ~~~~~~~~~~~~ -!!! error TS6133: 'i3' is declared but its value is never read. +!!! error TS6196: 'i3' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsAndParameters.errors.txt b/tests/baselines/reference/unusedLocalsAndParameters.errors.txt index 7ee0e0b8cb9..e9656c6f669 100644 --- a/tests/baselines/reference/unusedLocalsAndParameters.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndParameters.errors.txt @@ -2,7 +2,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(4,12): error TS6133: 'a' is de tests/cases/compiler/unusedLocalsAndParameters.ts(9,22): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(15,5): error TS6133: 'farrow' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(15,15): error TS6133: 'a' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParameters.ts(18,1): error TS6133: 'C' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParameters.ts(18,1): error TS6196: 'C' is declared but never used. tests/cases/compiler/unusedLocalsAndParameters.ts(20,12): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(23,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/unusedLocalsAndParameters.ts(23,11): error TS6133: 'v' is declared but its value is never read. @@ -52,7 +52,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(80,9): error TS6133: 'x' is de class C { ~~~~~~~ -!!! error TS6133: 'C' is declared but its value is never read. +!!! error TS6196: 'C' is declared but never used. // Method declaration paramter method(a) { ~ diff --git a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt index 31c825ce906..f86ec0d1cc7 100644 --- a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(2,1): error TS6133: 'handler1' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(2,1): error TS6196: 'handler1' is declared but never used. tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(5,1): error TS6133: 'foo' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6133: 'handler2' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6196: 'handler2' is declared but never used. ==== tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts (3 errors) ==== // unused type handler1 = () => void; ~~~~~~~~~~~~~ -!!! error TS6133: 'handler1' is declared but its value is never read. +!!! error TS6196: 'handler1' is declared but never used. function foo() { @@ -15,7 +15,7 @@ tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6133 !!! error TS6133: 'foo' is declared but its value is never read. type handler2 = () => void; ~~~~~~~~~~~~~ -!!! error TS6133: 'handler2' is declared but its value is never read. +!!! error TS6196: 'handler2' is declared but never used. foo(); } From b72abdb1204fbebd657bdb7eb6c0b028ebcd5089 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 24 Apr 2018 16:10:31 +0000 Subject: [PATCH 7/8] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 +++++++ .../diagnosticMessages.generated.json.lcl | 33 ++++++++++--------- .../diagnosticMessages.generated.json.lcl | 12 +++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++ 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 23b68db43f8..f6f14d4a402 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -906,6 +906,9 @@ + + + @@ -1008,6 +1011,9 @@ + + + @@ -6498,6 +6504,12 @@ + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index ca47b5dac95..5f93b90c20e 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -912,6 +912,15 @@ + + + + + + + + + @@ -1008,27 +1017,15 @@ - + - + - + - - - - - - - - - - - - @@ -6516,6 +6513,12 @@ + + + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 07300f3ab7c..235f19b459f 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -906,6 +906,9 @@ + + + @@ -1008,6 +1011,9 @@ + + + @@ -6498,6 +6504,12 @@ + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index dc4c01fcad4..c10ba98b4e0 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -905,6 +905,9 @@ + + + @@ -6497,6 +6500,12 @@ + + + + + + From 59765e2d86a7e36b827043a5ca75d49d2a7a88a3 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 24 Apr 2018 09:41:47 -0700 Subject: [PATCH 8/8] goToDefinition: Also add definitions for symbol if it does not match the signature symbol (#23657) --- src/services/goToDefinition.ts | 40 +++++++++++-------- ...ToDefinitionNewExpressionTargetNotClass.ts | 4 +- .../fourslash/goToDefinitionSignatureAlias.ts | 15 +++++++ tests/cases/fourslash/goToDefinition_super.ts | 2 +- .../tsxGoToDefinitionUnionElementType1.ts | 6 +-- 5 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 tests/cases/fourslash/goToDefinitionSignatureAlias.ts diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index f97a8338b05..977f9617353 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -18,13 +18,7 @@ namespace ts.GoToDefinition { } const typeChecker = program.getTypeChecker(); - - const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); - if (calledDeclaration) { - return [createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration)]; - } - - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = getSymbol(node, typeChecker); // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol @@ -32,15 +26,14 @@ namespace ts.GoToDefinition { return getDefinitionInfoForIndexSignatures(node, typeChecker); } - // If this is an alias, and the request came at the declaration location - // get the aliased symbol instead. This allows for goto def on an import e.g. - // import {A, B} from "mod"; - // to jump to the implementation directly. - if (symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) { - const aliased = typeChecker.getAliasedSymbol(symbol); - if (aliased.declarations) { - symbol = aliased; - } + const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); + if (calledDeclaration) { + const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration); + // For a function, if this is the original function definition, return just sigInfo. + // If this is the original constructor definition, parent is the class. + return typeChecker.getRootSymbols(symbol).some(s => calledDeclaration.symbol === s || calledDeclaration.symbol.parent === s) + ? [sigInfo] + : [sigInfo, ...getDefinitionFromSymbol(typeChecker, symbol, node)]; } // Because name in short-hand property assignment has two different meanings: property name and property value, @@ -158,6 +151,21 @@ namespace ts.GoToDefinition { }); } + function getSymbol(node: Node, checker: TypeChecker): Symbol | undefined { + const symbol = checker.getSymbolAtLocation(node); + // If this is an alias, and the request came at the declaration location + // get the aliased symbol instead. This allows for goto def on an import e.g. + // import {A, B} from "mod"; + // to jump to the implementation directly. + if (symbol && symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) { + const aliased = checker.getAliasedSymbol(symbol); + if (aliased.declarations) { + return aliased; + } + } + return symbol; + } + // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). diff --git a/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts b/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts index 02a6dca9d52..00f83323a0b 100644 --- a/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts +++ b/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts @@ -2,7 +2,7 @@ ////class C2 { ////} -////let I: { +////let /*I*/I: { //// /*constructSignature*/new(): C2; ////}; ////new [|/*invokeExpression1*/I|](); @@ -11,6 +11,6 @@ ////new [|/*invokeExpression2*/I2|](); verify.goToDefinition({ - invokeExpression1: "constructSignature", + invokeExpression1: ["constructSignature", "I"], invokeExpression2: "symbolDeclaration" }); diff --git a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts new file mode 100644 index 00000000000..07a5678f5d2 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts @@ -0,0 +1,15 @@ +/// + +////function /*f*/f() {} +////const /*g*/g = f; +////const /*h*/h = g; + +////[|/*useF*/f|](); +////[|/*useG*/g|](); +////[|/*useH*/h|](); + +verify.goToDefinition({ + useF: "f", + useG: ["f", "g"], + useH: ["f", "h"], +}); diff --git a/tests/cases/fourslash/goToDefinition_super.ts b/tests/cases/fourslash/goToDefinition_super.ts index 22f00aff7dc..edc7a40c376 100644 --- a/tests/cases/fourslash/goToDefinition_super.ts +++ b/tests/cases/fourslash/goToDefinition_super.ts @@ -22,7 +22,7 @@ verify.goToDefinition({ // Super in call position goes to constructor. - super: "ctr", + super: ["ctr", "B"], // Super in any other position goes to the superclass. superExpression: "B", superBroken: [] diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts index d6b5dfab709..0e899c71d2b 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts @@ -18,9 +18,9 @@ //// return

World

; //// } -//// var SFCComp = SFC1 || SFC2; +//// var /*def*/SFCComp = SFC1 || SFC2; //// <[|SFC/*one*/Comp|] x /> verify.goToDefinition({ - "one": "pt1" -}) \ No newline at end of file + "one": ["pt1", "def"], +});