Typescript: Confusing/Inconsistent error message with circular type definition

Created on 4 Jul 2018  路  7Comments  路  Source: microsoft/TypeScript


TypeScript Version: 2.9.1


Search Terms:
flatMap is:open

Code

type PlainObjectItem = string | number | boolean | null

interface PlainObject {
    [key: string]: PlainObjectItem | PlainObjectItem[] | PlainObject
}

const hoge: PlainObject = {
    key1: 'hoge',
    key2: {
        key21: 'aaa',
        key22: false,
        key23: {
            key231: [1,2,3,4,5],
            date: new Date()
        }
    }
}

Expected behavior:
Error message is something like 'new Date()' is not assignable to type 'PlainObjectItem | PlainObjectItem[] | PlainObject'.

Actual behavior:
Property 'flatMap' is missing in type '{ key21: string; key22: false; key23: { key231: number[]; date: Date; }; }'.

Playground Link:
http://www.typescriptlang.org/play/#src=type%20PlainObjectItem%20%3D%20string%20%7C%20number%20%7C%20boolean%20%7C%20null%0D%0A%0D%0Ainterface%20PlainObject%20%7B%0D%0A%09%5Bkey%3A%20string%5D%3A%20PlainObjectItem%20%7C%20PlainObjectItem%5B%5D%20%7C%20PlainObject%0D%0A%7D%0D%0A%0D%0Aconst%20hoge%3A%20PlainObject%20%3D%20%7B%0D%0A%09key1%3A%20'hoge'%2C%0D%0A%09key2%3A%20%7B%0D%0A%09%09key21%3A%20'aaa'%2C%0D%0A%09%09key22%3A%20false%2C%0D%0A%09%09key23%3A%20%7B%0D%0A%09%09%09key231%3A%20%5B1%2C2%2C3%2C4%2C5%5D%2C%0D%0A%09%09%09date%3A%20new%20Date()%0D%0A%09%09%7D%0D%0A%09%7D%0D%0A%7D

(This example says Property 'length' is missing...)

Related Issues:

Bug Error Messages

All 7 comments

If this error message is intended by design, feel free to close, but I'm not smart enough to understand that message.

I think the error message is confusing.

Adding the Date type at PlainObjectItem solve the error:

type PlainObjectItem = string | number | boolean | null | Date

interface PlainObject {
    [key: string]: PlainObjectItem | PlainObjectItem[] | PlainObject
}

const hoge: PlainObject = {
    key1: 'hoge',
    key2: {
        key21: 'aaa',
        key22: false,
        key23: {
            key231: [1,2,3,4,5],
            date: new Date()
        }
    }
}

Playground link

Just in case, the point of this issue is not solving the error, but the confusing error message itself.

@DanielRosenwasser As part of the error message improvement push, we should track the general category of choosing the "best" constituent of a union when reporting non-assignability.

Currently we throw out things that are disproven by a discriminant property, but we could probably do better by attempting to throw out candidate targets that seem unfixably incompatible:

  • The target has a numeric index signature or a call signature and the source doesn't
  • The target is a primitive and the source isn't
  • The target is an object and the source isn't

IOW the "ideal" error message always refers to a missing property or a property with the wrong type, or relates two primitives.

But probably everything I said up there is disproved by a different example where this generates manifestly worse error messages.

What the... even after our improvements, the current message is

Type '{ key21: string; key22: false; key23: { key231: number[]; date: Date; }; }' is not assignable to type 'string | number | boolean | PlainObject | PlainObjectItem[]'.
  Type '{ key21: string; key22: false; key23: { key231: number[]; date: Date; }; }' is not assignable to type 'string'.ts(2322)

Well, uh, I've got it to be less dumb but longer.

error TS2322: Type '{ key21: string; key22: false; key23: { key231: number[]; date: Date; }; }' is not assignable to type 'string | number | boolean | PlainObject | PlainObjectItem[] | null'.
  Type '{ key21: string; key22: false; key23: { key231: number[]; date: Date; }; }' is not assignable to type 'PlainObject'.
    Property 'key23' is incompatible with index signature.
      Type '{ key231: number[]; date: Date; }' is not assignable to type 'string | number | boolean | PlainObject | PlainObjectItem[] | null'.
        Type '{ key231: number[]; date: Date; }' is not assignable to type 'PlainObject'.
          Property 'date' is incompatible with index signature.
            Type 'Date' is not assignable to type 'string | number | boolean | PlainObject | PlainObjectItem[] | null'.
              Type 'Date' is not assignable to type 'PlainObject'.
                Index signature is missing in type 'Date'.

Fixed on master.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jonathandturner picture jonathandturner  路  147Comments

chanon picture chanon  路  138Comments

metaweta picture metaweta  路  140Comments

disshishkov picture disshishkov  路  224Comments

RyanCavanaugh picture RyanCavanaugh  路  205Comments