Generic type union assignment via Pick throws TS2322 #28080
Open
Description
TypeScript Version: 3.1.3 and 3.2.0-dev.20181023
Works in Version 3.0.3
Search Terms: generic union assignment TS2322 setState
Code
interface A {
a: string;
}
class Base<T> {
prop: T;
update<U extends keyof T>(props: Pick<T, U>) { /* like react setState */ }
}
class Test<T> extends Base<A & T> {
test() {
const str: string = "foo";
this.prop.a = str; //ok
this.update({
a: str //err TS2322
});
}
}
// explicitly remove overloading properties
type SaveMerge<T, R> = T & Pick<R, Exclude<keyof R, keyof T>>;
class Test2<T> extends Base<SaveMerge<A, T>> {
test() {
const str: string = "foo";
this.prop.a = str; //ok
this.update({
a: str //err TS2322
});
}
}
Expected behavior:
Compiles fine as in 3.0.3
Actual behavior:
test.ts:18:13 - error TS2322: Type 'string' is not assignable to type 'string & T["a"]'.
Type 'string' is not assignable to type 'T["a"]'.
18 a: str //err
~
test.ts:3:5
3 a: string;
~
The expected type comes from property 'a' which is declared here on type 'Pick<A & T, "a">'
test.ts:29:13 - error TS2322: Type 'string' is not assignable to type 'string & T["a"]'.
Type 'string' is not assignable to type 'T["a"]'.
29 a: str //err
~
test.ts:3:5
3 a: string;
~
The expected type comes from property 'a' which is declared here on type 'Pick<SaveMerge<A, T>, "a">'
Related Issues:
Maybe #26274