Skip to content

Index Signature Fails with Generics and Intersection Types #23673

@AnyhowStep

Description

@AnyhowStep

TypeScript Version: Version 2.9.0-dev.20180405

Search Terms: extends generic intersection index

Code

type SomeType<T> = {
    [k in keyof T]: any;
};

function generic<Base, Derived extends SomeType<Base>>() {
    const derived: Derived = null as any;
    const test: { test: string } = null as any;
    const both: Derived & { test : string } = null as any;

    const works0: SomeType<Base> = derived;
    const works1: SomeType<Derived> = derived;
    const works2: SomeType<{ test: string }> = test;

    //This fails unexpectedly    
    const fails0: SomeType<Base & { test: string }> = both;
}

interface ConcreteBase {
    a: string,
    b: string,
}
interface ConcreteDerived {
    a: string,
    b: string,
    c: string,
}
const derived: ConcreteDerived = null as any;
const test: { test: string } = null as any;
const both: ConcreteDerived & { test : string } = null as any;

const works0: SomeType<ConcreteBase> = derived;
const works1: SomeType<ConcreteDerived> = derived;
const works2: SomeType<{ test: string }> = test;

const worksOutFine: SomeType<ConcreteBase & { test: string }> = both;

Expected behavior:

fails0 in generic() should compile

Actual behavior:

fails0 in generic() fails

Playground Link: Link here

Intuitively, to me, it should work out fine.

  • Derived has all the fields of Base; possibly more.
  • I added one extra field test.
  • Derived is assignable to Base
  • Derived & { test: string } should be assignable to Base & { test: string }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions