Skip to content

Confusing difference between types and interfaces when intersected with string indexes #24970

Closed
@ekilah

Description

@ekilah

TypeScript Version: 2.8.3

Search Terms: intersection types and interfaces seem to behave differently. Inconsistent 'property 'x' of type 'y' is not assignable to string index type

Code

interface IJSONObject {
  [key: string]: string | number | boolean | IJSONObject
}

// we want to enforce that some objects have an `id` field
// with a `type`. 
type TIdElement = {
  id: string
}

// here's an object with an `id` and a `day`.
// we've enforced the `id` member with a `type`.
type WithType = TIdElement & {
    day: Date,
}

// we could use an interface to enforce the same idea that
// things have an `id`
interface IIdElement {
  id: string
}

// here's another object with an `id` and a `day`,
// this time enforced with an `interface` instead.
type WithInterface = IIdElement & {
    day: Date,
}

// only the version where `id` was added via an intersection
// with an `interface` causes a type error.
//
// expected behavior: a type error should happen with both,
// because `Date` is not in `IJSONObject`'s index signature
interface ITest extends IJSONObject {
    baz: WithType // no error, why?
    foo: WithInterface    // error, as expected
}

Expected behavior:
a type error should happen with both,
because Date is not in IJSONObject's index signature

Actual behavior:
WithType doesn't cause an error, even though Date shouldn't be allowed.

Playground Link: link

Related Issues: possibly #18075 but I'm not really sure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions