Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 13.8k
Fixed an issue with unsound indexed access on unknown type param#49729
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts(2,12): error TS2531: Object is possibly 'null'. | ||
| tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts(5,12): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. | ||
| tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts(8,12): error TS2531: Object is possibly 'null'. | ||
| tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts(11,13): error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. | ||
| ==== tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts (4 errors) ==== | ||
| function test<T, K extends keyof T>(t: T, k: K) { | ||
| return t[k]; | ||
| ~ | ||
| !!! error TS2531: Object is possibly 'null'. | ||
| } | ||
| test(null, 'foo') | ||
ContributorAuthor 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've included those calls as there was a temporary regression related to this, you can check out here. I've figured out that this might be worth it to add here as part of the regression tests | ||
| ~~~~~ | ||
| !!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. | ||
| function test2<T extends unknown, K extends keyof T>(t: T, k: K) { | ||
| return t[k]; | ||
| ~ | ||
| !!! error TS2531: Object is possibly 'null'. | ||
| } | ||
| test2(null, 'foo') | ||
| ~~~~~ | ||
| !!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| === tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts === | ||
| function test<T, K extends keyof T>(t: T, k: K) { | ||
| >test : Symbol(test, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 0)) | ||
| >T : Symbol(T, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 14)) | ||
| >K : Symbol(K, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 16)) | ||
| >T : Symbol(T, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 14)) | ||
| >t : Symbol(t, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 36)) | ||
| >T : Symbol(T, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 14)) | ||
| >k : Symbol(k, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 41)) | ||
| >K : Symbol(K, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 16)) | ||
| return t[k]; | ||
| >t : Symbol(t, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 36)) | ||
| >k : Symbol(k, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 41)) | ||
| } | ||
| test(null, 'foo') | ||
| >test : Symbol(test, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 0, 0)) | ||
| function test2<T extends unknown, K extends keyof T>(t: T, k: K) { | ||
| >test2 : Symbol(test2, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 4, 17)) | ||
| >T : Symbol(T, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 15)) | ||
| >K : Symbol(K, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 33)) | ||
| >T : Symbol(T, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 15)) | ||
| >t : Symbol(t, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 53)) | ||
| >T : Symbol(T, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 15)) | ||
| >k : Symbol(k, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 58)) | ||
| >K : Symbol(K, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 33)) | ||
| return t[k]; | ||
| >t : Symbol(t, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 53)) | ||
| >k : Symbol(k, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 6, 58)) | ||
| } | ||
| test2(null, 'foo') | ||
| >test2 : Symbol(test2, Decl(genericUnknownTypeParamWithKeyofIndexedAccess.ts, 4, 17)) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| === tests/cases/compiler/genericUnknownTypeParamWithKeyofIndexedAccess.ts === | ||
| function test<T, K extends keyof T>(t: T, k: K) { | ||
| >test : <T, K extends keyof T>(t: T, k: K) => NonNullable<T>[K] | ||
| >t : T | ||
| >k : K | ||
| return t[k]; | ||
| >t[k] : NonNullable<T>[K] | ||
| >t : T | ||
| >k : K | ||
| } | ||
| test(null, 'foo') | ||
| >test(null, 'foo') : never | ||
| >test : <T, K extends keyof T>(t: T, k: K) => NonNullable<T>[K] | ||
| >null : null | ||
| >'foo' : "foo" | ||
| function test2<T extends unknown, K extends keyof T>(t: T, k: K) { | ||
| >test2 : <T extends unknown, K extends keyof T>(t: T, k: K) => NonNullable<T>[K] | ||
| >t : T | ||
| >k : K | ||
| return t[k]; | ||
| >t[k] : NonNullable<T>[K] | ||
| >t : T | ||
| >k : K | ||
| } | ||
| test2(null, 'foo') | ||
| >test2(null, 'foo') : never | ||
| >test2 : <T extends unknown, K extends keyof T>(t: T, k: K) => NonNullable<T>[K] | ||
| >null : null | ||
| >'foo' : "foo" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // @strict: true | ||
| // @noEmit: true | ||
| function test<T, K extends keyof T>(t: T, k: K) { | ||
| return t[k]; | ||
| } | ||
| test(null, 'foo') | ||
| function test2<T extends unknown, K extends keyof T>(t: T, k: K) { | ||
| return t[k]; | ||
| } | ||
| test2(null, 'foo') |
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.
I'm not super sure if this is the best check, I've based this on the logic from
getTypeFacts:https://github.dev/microsoft/TypeScript/blob/b379e7fc791fc8646d9d255adce5127a6ab83099/src/compiler/checker.ts#L23562-L23564
In fact, I think this case probably should report a similar error like the one introduced here:
https://github.com/microsoft/TypeScript/pull/49119/files#diff-d9ab6589e714c71e657f601cf30ff51dfc607fc98419bf72e04f6b0fa92cc4b8R18815-R18817
Note that this logic has been further adjusted in:
https://github.com/microsoft/TypeScript/pull/49481/files#diff-d9ab6589e714c71e657f601cf30ff51dfc607fc98419bf72e04f6b0fa92cc4b8R18795
cc Anders Hejlsberg (@ahejlsberg)