Description
TypeScript Version: Since 3.4.1, I had no issue in 3.4.0-rc and below
Search Terms:
Type inference regression in TS 3.4
(I know there are a couple issues on regressions introduced with TS 3.4 but they're not similar, and mine wasn't there in the RC)
Code
interface Entry {
comment?: string;
}
interface Entity {
fields: {[key: string]: Entry};
}
type Fields<E extends Entity> = {
[P in keyof E["fields"]]: E["fields"][P]
};
type Nodes<T = any> = {
[P in keyof T]: T[P] extends Entity
? Fields<T[P]>
: T[P]
};
function makeEntityStore<T extends Record<string, Entity>>(config: T): Nodes<T> {
return {} as Nodes<T>
}
const myTest = makeEntityStore({ test: { fields: { id: {} } } });
myTest.test
Expected behavior:
myTest.test
's type should be Fields<{fields: {id: {}}>
Actual behavior:
myTest.test
's type is Fields<Entity & {fields: {id: {}}>
This is the simplest repro I could manage for the bug I encounter in my project when I try to upgrade from the RC to any final version (3.4.1, 3.4.2 or 3.4.3, and it's still there in the latest nightly I tried). This might look inoffensive presented like that, but in the "real world" the types presented here are way more complex and that added intersection with the constraint type messes up literally every usage I get from that function. I have to stay on the RC because of this.
Actually, there is a very simple tweak you can do to this exemple to get the expected inference behavior, which is removing the comment?: string
property on Entry
. Obviously, this isn't an acceptable solution, but it makes all of that look even more like a tiny bug that made its way into the compiler during the finalization of the 3.4 version.
Playground Link: Here