microsoft / microsoft/TypeScript
TypeScript does not infer the type correctly after two layer Mapped Types.
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
TypeScript Version: 3.9.0-beta
Search Terms:
Lookup Types, Mapped Types
Code
This is Okay:
interface APIs {
readonly getUserProfile: {
readonly Parameter: {
readonly id: string;
};
readonly Response: {
'200': {
readonly id: string;
readonly name: string;
readonly gender: boolean;
};
};
};
}
export type ValueType<T extends object> = T[keyof T];
export type PropertyType<T extends object, K extends string> = K extends keyof T
? T[K]
: never;
type MyFetch = {
[operationId in keyof APIs]: (
param: PropertyType<APIs[operationId], 'Parameter'>,
) => Promise<
ValueType<PropertyType<APIs[operationId], 'Response'>>
>;
};
And this is Error: Type 'APIs[server][string]' is not assignable to type 'object'
interface APIs {
readonly server1: {
readonly getUserProfile: {
readonly Parameter: {
readonly id: string;
};
readonly Response: {
'200': {
readonly id: string;
readonly name: string;
readonly gender: boolean;
};
};
};
};
}
export type ValueType<T extends object> = T[keyof T];
export type PropertyType<T extends object, K extends string> = K extends keyof T
? T[K]
: never;
type MyFetch = {
[server in keyof APIs]: {
[operationId in keyof APIs[server]]: (
param: PropertyType<APIs[server][operationId], 'Parameter'>,
) => Promise<
ValueType<PropertyType<APIs[server][operationId], 'Response'>>
>;
};
};
And this is Ok
interface APIs {
readonly server1: {
readonly getUserProfile: {
readonly Parameter: {
readonly id: string;
};
readonly Response: {
'200': {
readonly id: string;
readonly name: string;
readonly gender: boolean;
};
};
};
};
}
export type ValueType<T extends object> = T[keyof T];
export type PropertyType<T extends object, K extends string> = K extends keyof T
? T[K]
: never;
type MyFetch = {
[server in keyof APIs]: {
[operationId in keyof APIs[server]]: (
param: PropertyType<{} & APIs[server][operationId], 'Parameter'>,
) => Promise<
ValueType<{} & PropertyType<{} & APIs[server][operationId], 'Response'>>
>;
};
};
Expected behavior:
remove three {} & and no error.
Actual behavior:
Playground Link:
Related Issues:
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the Error Playground Link with TypeScript 3.9.0-beta and compare it with the two Ok Playground Links. Investigate the mapped-type and lookup-type inference path responsible for the reported constraint error. Done means the three {} intersections can be removed without an error in the reproduced example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100