Skip to content

mixing generics, Pick, Exclude and intersection types fails to compile in 3.1.0 #28274

Open
@seansfkelley

Description

@seansfkelley

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

Related Issues: #27201, #27928

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: Indexed Access TypesThe issue relates to accessing subtypes via index access

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions