-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Defer resolution of indexed access types with reducible object types #53098
Conversation
@typescript-bot test this |
Heya @ahejlsberg, I've started to run the abridged perf test suite on this PR at 8334e30. You can monitor the build here. Update: The results are in! |
Heya @ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at 8334e30. You can monitor the build here. Update: The results are in! |
Heya @ahejlsberg, I've started to run the diff-based top-repos suite on this PR at 8334e30. You can monitor the build here. Update: The results are in! |
Heya @ahejlsberg, I've started to run the extended test suite on this PR at 8334e30. You can monitor the build here. |
Heya @ahejlsberg, I've started to run the diff-based user code test suite on this PR at 8334e30. You can monitor the build here. Update: The results are in! |
@ahejlsberg Here are the results of running the user test suite comparing Everything looks good! |
@ahejlsberg Here they are:Comparison Report - main..53098
System
Hosts
Scenarios
Developer Information: |
Hey @ahejlsberg, the results of running the DT tests are ready. |
@ahejlsberg Here are the results of running the top-repos suite comparing Everything looks good! |
|
||
// Additional repro from 53030 | ||
|
||
type GetPayload<P extends Payload, K extends keyof P> = P extends { dataType: K } ? P["data"] : never; |
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.
perhaps it would still be worthwhile to include a test from #51161? that one was even more suspicious as the index access in the true branch was using the same property name as the one in the extendsType
. This additional repro is using a different one
type GetPayload<P extends Payload, K extends keyof P> = P extends { dataType: K } ? P["data"] : never; | |
type GetPayload<P extends Payload, K extends keyof P> = P extends { dataType: K } ? P["data"] : never; | |
// repro from 51161 | |
export type AnyOneof = { oneofKind: string; [k: string]: unknown } | { oneofKind: undefined }; | |
export type AnyOneofKind<T extends AnyOneof> = T extends { oneofKind: keyof T } | |
? T['oneofKind'] | |
: never; | |
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.
Sure, I'll add the extra test.
@typescript-bot pack this edit: I thought anyone could request a build... I think this fixes an issue I'm having so I'd like to test it in the playground. |
@typescript-bot pack this |
Heya @ahejlsberg, I've started to run the tarball bundle task on this PR at 20827a5. You can monitor the build here. |
Hey @ahejlsberg, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build and an npm module you can use via |
Thanks! Looks like it doesn't resolve my issue, unfortunately. It looks like the same basic pattern to me -- is this expected after the fix? const SomeRpcEndpointId = 'someRpcEndpoint' as const ;
type SomeRpcEndpointId = typeof SomeRpcEndpointId;
interface SomeRpcEndpointActions {
doFoo: {
in: string;
out: number;
};
doBar: {
in: boolean;
out: boolean;
};
}
type AllRpcEndpoints = {
[SomeRpcEndpointId]: SomeRpcEndpointActions;
};
type InvokeRpc = <H extends keyof AllRpcEndpoints, A extends keyof AllRpcEndpoints[H]>(
handler: H,
action: A,
payload: AllRpcEndpoints[H][A]['in'],
) => Promise<AllRpcEndpoints[H][A]['out']>;
declare const invokeRpc: InvokeRpc;
// Despite the compiler errors above, this does type-check correctly.
const result: boolean = await invokeRpc('someRpcEndpoint', 'doBar', true);
// Workaround inspired by https://github.com/microsoft/TypeScript/issues/53030#issuecomment-1448934975.
type GetIn<T> = T extends { in: any } ? T['in'] : never;
type GetOut<T> = T extends { out: any } ? T['out'] : never;
type InvokeRpcWorkaround = <H extends keyof AllRpcEndpoints, A extends keyof AllRpcEndpoints[H]>(
handler: H,
action: A,
payload: GetIn<AllRpcEndpoints[H][A]>,
) => Promise<GetOut<AllRpcEndpoints[H][A]>>;
declare const invokeRpcWorkaround: InvokeRpcWorkaround;
// Type-checks as expected.
const resultWorkaround: boolean = await invokeRpcWorkaround('someRpcEndpoint', 'doBar', true);
export {}; // appease the compiler |
@seansfkelley you are looking for a fix for this issue. |
This reuses some of the machinery introduced in #46812 to also defer resolution of indexed access types with reducible object types. The additional issue I mention here is actually caused by #46812 always deferring
keyof
for reducible types, making it impossible to explore their constraints. That's fixed in this PR by a new flag ongetIndexType
that disables deferral.EDIT: Turns out the additional issue is a duplicate of #51161. This also means that this PR supercedes #51176.
Fixes #51161.
Fixes #53030.