Open
Description
TypeScript Version: 3.2.0-dev.20181031
Search Terms: generic pick exclude keyof intersection spread
Code
type TWithFoo<T> = Pick<T, Exclude<keyof T, "foo">> & { foo: string };
const foobar: TWithFoo<{ foo: number; bar: string }> = {
foo: "foo",
bar: "bar",
};
function strictSpread<T, K extends keyof T>(
original: T,
override: Pick<T, K> | T
): T {
return Object.assign({}, original, override);
}
// Works as expected.
strictSpread(foobar, {
foo: "foo",
bar: "bar",
});
// Fails as expected.
strictSpread(foobar, {
baz: "foo",
});
function fn<T extends object>() {
const o: TWithFoo<T> = null as any;
// Fails unexpectedly.
strictSpread(o, {
foo: "foo",
});
}
Expected behavior:
The line annotated "fails unexpectedly" should compile successfully.
AFAICT this change happened between 3.1.0-dev.20180825
and 3.1.0-dev.20180828
.
Actual behavior:
The line annotated "fails unexpectedly" does not compile, though it used to in earlier versions.
The error reported is
Type '"foo"' is not assignable to type 'T["foo"] & string'.
Type '"foo"' is not assignable to type 'T["foo"]'.
But TWithFoo
is specifically defined to ignore any existing foo
key and replace it with string
.
Playground Link: link