-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Resolve keyof and index operations instead of their targets. #58758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11644,6 +11644,14 @@ export function unwrapParenthesizedExpression(o: Expression) { | |
return o; | ||
} | ||
|
||
/** @internal */ | ||
export function unwrapParenthesizedType(o: TypeNode) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm surprised we don't already have this helper... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was surprised too. But I could not find it if it exists. There is one that walks up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, it's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh. Didn't think to look for that. I'll fix it tomorrow. |
||
while (o.kind === SyntaxKind.ParenthesizedType) { | ||
o = (o as ParenthesizedTypeNode).type; | ||
} | ||
return o; | ||
} | ||
|
||
/** @internal */ | ||
export function hasInferredType(node: Node): node is HasInferredType { | ||
Debug.type<HasInferredType>(node); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
//// [tests/cases/compiler/declarationEmitResolveTypesIfNotReusable.ts] //// | ||
|
||
//// [decl.ts] | ||
const u = "X"; | ||
type A = { a: { b : "value of b", notNecessary: typeof u }} | ||
const a = { a: "value of a", notNecessary: u } as const | ||
|
||
|
||
export const o1 = (o: A['a']['b']) => {} | ||
|
||
export const o2 = (o: (typeof a)['a']) => {} | ||
export const o3 = (o: typeof a['a']) => {} | ||
|
||
export const o4 = (o: keyof (A['a'])) => {} | ||
|
||
//// [main.ts] | ||
import * as d from './decl' | ||
|
||
export const f = {...d} | ||
|
||
//// [decl.js] | ||
const u = "X"; | ||
const a = { a: "value of a", notNecessary: u }; | ||
export const o1 = (o) => { }; | ||
export const o2 = (o) => { }; | ||
export const o3 = (o) => { }; | ||
export const o4 = (o) => { }; | ||
//// [main.js] | ||
import * as d from './decl'; | ||
export const f = { ...d }; | ||
|
||
|
||
//// [decl.d.ts] | ||
declare const u = "X"; | ||
type A = { | ||
a: { | ||
b: "value of b"; | ||
notNecessary: typeof u; | ||
}; | ||
}; | ||
declare const a: { | ||
readonly a: "value of a"; | ||
readonly notNecessary: "X"; | ||
}; | ||
export declare const o1: (o: A["a"]["b"]) => void; | ||
export declare const o2: (o: (typeof a)["a"]) => void; | ||
export declare const o3: (o: (typeof a)["a"]) => void; | ||
export declare const o4: (o: keyof A["a"]) => void; | ||
export {}; | ||
//// [main.d.ts] | ||
export declare const f: { | ||
o1: (o: "value of b") => void; | ||
o2: (o: "value of a") => void; | ||
o3: (o: "value of a") => void; | ||
o4: (o: "b" | "notNecessary") => void; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//// [tests/cases/compiler/declarationEmitResolveTypesIfNotReusable.ts] //// | ||
|
||
=== decl.ts === | ||
const u = "X"; | ||
>u : Symbol(u, Decl(decl.ts, 0, 5)) | ||
|
||
type A = { a: { b : "value of b", notNecessary: typeof u }} | ||
>A : Symbol(A, Decl(decl.ts, 0, 14)) | ||
>a : Symbol(a, Decl(decl.ts, 1, 10)) | ||
>b : Symbol(b, Decl(decl.ts, 1, 15)) | ||
>notNecessary : Symbol(notNecessary, Decl(decl.ts, 1, 33)) | ||
>u : Symbol(u, Decl(decl.ts, 0, 5)) | ||
|
||
const a = { a: "value of a", notNecessary: u } as const | ||
>a : Symbol(a, Decl(decl.ts, 2, 5)) | ||
>a : Symbol(a, Decl(decl.ts, 2, 11)) | ||
>notNecessary : Symbol(notNecessary, Decl(decl.ts, 2, 28)) | ||
>u : Symbol(u, Decl(decl.ts, 0, 5)) | ||
>const : Symbol(const) | ||
|
||
|
||
export const o1 = (o: A['a']['b']) => {} | ||
>o1 : Symbol(o1, Decl(decl.ts, 5, 12)) | ||
>o : Symbol(o, Decl(decl.ts, 5, 19)) | ||
>A : Symbol(A, Decl(decl.ts, 0, 14)) | ||
|
||
export const o2 = (o: (typeof a)['a']) => {} | ||
>o2 : Symbol(o2, Decl(decl.ts, 7, 12)) | ||
>o : Symbol(o, Decl(decl.ts, 7, 19)) | ||
>a : Symbol(a, Decl(decl.ts, 2, 5)) | ||
|
||
export const o3 = (o: typeof a['a']) => {} | ||
>o3 : Symbol(o3, Decl(decl.ts, 8, 12)) | ||
>o : Symbol(o, Decl(decl.ts, 8, 19)) | ||
>a : Symbol(a, Decl(decl.ts, 2, 5)) | ||
|
||
export const o4 = (o: keyof (A['a'])) => {} | ||
>o4 : Symbol(o4, Decl(decl.ts, 10, 12)) | ||
>o : Symbol(o, Decl(decl.ts, 10, 19)) | ||
>A : Symbol(A, Decl(decl.ts, 0, 14)) | ||
|
||
=== main.ts === | ||
import * as d from './decl' | ||
>d : Symbol(d, Decl(main.ts, 0, 6)) | ||
|
||
export const f = {...d} | ||
>f : Symbol(f, Decl(main.ts, 2, 12)) | ||
>d : Symbol(d, Decl(main.ts, 0, 6)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//// [tests/cases/compiler/declarationEmitResolveTypesIfNotReusable.ts] //// | ||
|
||
=== decl.ts === | ||
const u = "X"; | ||
>u : "X" | ||
> : ^^^ | ||
>"X" : "X" | ||
> : ^^^ | ||
|
||
type A = { a: { b : "value of b", notNecessary: typeof u }} | ||
>A : A | ||
> : ^ | ||
>a : { b: "value of b"; notNecessary: typeof u; } | ||
> : ^^^^^ ^^^^^^^^^^^^^^^^ ^^^ | ||
>b : "value of b" | ||
> : ^^^^^^^^^^^^ | ||
>notNecessary : "X" | ||
> : ^^^ | ||
>u : "X" | ||
> : ^^^ | ||
|
||
const a = { a: "value of a", notNecessary: u } as const | ||
>a : { readonly a: "value of a"; readonly notNecessary: "X"; } | ||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
>{ a: "value of a", notNecessary: u } as const : { readonly a: "value of a"; readonly notNecessary: "X"; } | ||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
>{ a: "value of a", notNecessary: u } : { readonly a: "value of a"; readonly notNecessary: "X"; } | ||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
>a : "value of a" | ||
> : ^^^^^^^^^^^^ | ||
>"value of a" : "value of a" | ||
> : ^^^^^^^^^^^^ | ||
>notNecessary : "X" | ||
> : ^^^ | ||
>u : "X" | ||
> : ^^^ | ||
|
||
|
||
export const o1 = (o: A['a']['b']) => {} | ||
>o1 : (o: A["a"]["b"]) => void | ||
> : ^ ^^ ^^^^^^^^^ | ||
>(o: A['a']['b']) => {} : (o: A["a"]["b"]) => void | ||
> : ^ ^^ ^^^^^^^^^ | ||
>o : "value of b" | ||
> : ^^^^^^^^^^^^ | ||
|
||
export const o2 = (o: (typeof a)['a']) => {} | ||
>o2 : (o: (typeof a)["a"]) => void | ||
> : ^ ^^^ ^ ^^^^^^^^^ | ||
>(o: (typeof a)['a']) => {} : (o: (typeof a)["a"]) => void | ||
> : ^ ^^^ ^ ^^^^^^^^^ | ||
>o : "value of a" | ||
> : ^^^^^^^^^^^^ | ||
>a : { readonly a: "value of a"; readonly notNecessary: "X"; } | ||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
export const o3 = (o: typeof a['a']) => {} | ||
>o3 : (o: (typeof a)["a"]) => void | ||
> : ^ ^^^ ^ ^^^^^^^^^ | ||
>(o: typeof a['a']) => {} : (o: (typeof a)["a"]) => void | ||
> : ^ ^^^ ^ ^^^^^^^^^ | ||
>o : "value of a" | ||
> : ^^^^^^^^^^^^ | ||
>a : { readonly a: "value of a"; readonly notNecessary: "X"; } | ||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
export const o4 = (o: keyof (A['a'])) => {} | ||
>o4 : (o: keyof A["a"]) => void | ||
> : ^ ^^ ^^^^^^^^^ | ||
>(o: keyof (A['a'])) => {} : (o: keyof A["a"]) => void | ||
> : ^ ^^ ^^^^^^^^^ | ||
>o : "b" | "notNecessary" | ||
> : ^^^^^^^^^^^^^^^^^^^^ | ||
|
||
=== main.ts === | ||
import * as d from './decl' | ||
>d : typeof d | ||
> : ^^^^^^^^ | ||
|
||
export const f = {...d} | ||
>f : { o1: (o: "value of b") => void; o2: (o: "value of a") => void; o3: (o: "value of a") => void; o4: (o: "b" | "notNecessary") => void; } | ||
> : ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
>{...d} : { o1: (o: "value of b") => void; o2: (o: "value of a") => void; o3: (o: "value of a") => void; o4: (o: "b" | "notNecessary") => void; } | ||
> : ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
>d : typeof d | ||
> : ^^^^^^^^ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// @declaration: true | ||
// @target: esnext | ||
|
||
// @filename: decl.ts | ||
const u = "X"; | ||
type A = { a: { b : "value of b", notNecessary: typeof u }} | ||
const a = { a: "value of a", notNecessary: u } as const | ||
|
||
|
||
export const o1 = (o: A['a']['b']) => {} | ||
|
||
export const o2 = (o: (typeof a)['a']) => {} | ||
export const o3 = (o: typeof a['a']) => {} | ||
|
||
export const o4 = (o: keyof (A['a'])) => {} | ||
|
||
// @filename: main.ts | ||
import * as d from './decl' | ||
|
||
export const f = {...d} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tryVisitIndexedAccess