Closed
Description
TypeScript Version: 3.5.1 (also happens with @next
)
Search Terms: ternary, ternary intersection/union, property accessor intersection/union
Code
interface FooBar {
foo: string;
bar: number;
}
const set = (foobar: FooBar, key: 'foo' | 'bar', value: string) => {
foobar[key] = key === 'foo' ? value : Number(value);
};
or
class FooBar {
foo?: string;
bar?: number;
set(key: 'foo' | 'bar', value: string) {
this[key] = key === 'foo' ? value : Number(value);
}
}
Expected behavior:
Works (it did up to version 3.4.5).
Actual behavior:
An intersection type is inferred for foobar[key]
(or this[key]
), however I think it should be a union type.
index.ts:7:3 - error TS2322: Type 'string | number' is not assignable to type 'string & number'.
Type 'string' is not assignable to type 'string & number'.
Type 'string' is not assignable to type 'number'.
7 foobar[key] = key === 'foo' ? value : Number(value);
~~~~~~~~~~~
index.ts:6:3 - error TS2322: Type 'string | number' is not assignable to type 'undefined'.
Type 'string' is not assignable to type 'undefined'.
6 this[key] = key === 'foo' ? value : Number(value);
~~~~~~~~~
Playground Link:
Useless because this used to work up to version 3.4.5 (and the playground is stuck at version 3.3.3).
Related Issues:
Maybe #9239
If I use an if/else instead of the ternary operator, it works because it's easier to figure out the type of this[key]
:
if (key === 'foo') {
this[key] = value;
} else {
this[key] = Number(value);
}