See the code below or the corresponding playground:
type SomeType = {
[P in 'u']?: string;
} & {
[P in 'a' | 'b' | 'c' | 'd']?: SomeType;
}
const st: SomeType = {
u: '1',
a: {
u: '2',
b: {
u: '3',
c: {
d: {
},
e: 1, // why doesn't this cause an error here? oO thank you!
}
},
},
e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
};
I don't know what else to say here. If you comment out the last e: 1
then no ts error is generated. Why?
Edit: OK, like wtf.
type SomeType = {
u?: string;
a?: SomeType;
b?: SomeType;
c?: SomeType;
d?: SomeType;
}
const st: SomeType = {
u: '1',
a: {
u: '2',
b: {
u: '3',
c: {
d: {
},
e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
}
},
},
e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
};
Edit: Here is the fixed version I created with the advice from @tokland that recursion with intersection is broken.
type P = 'u';
type Q = 'a' | 'b' | 'c' | 'd';
type SomeType = {
[K in (P | Q)]?: K extends P
? string
: SomeType
};
const st: SomeType = {
u: '1',
a: {
u: '2',
b: {
u: '3',
c: {
d: {
},
e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
}
},
},
e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
};
CodePudding user response:
It's a known bug, excess property check for nested type intersections worked fine up until 3.8:
https://github.com/microsoft/TypeScript/issues/47935
3.8: working
3.9: not working