Home > Net >  Error in recursive mapped type goes undetected. Why?
Error in recursive mapped type goes undetected. Why?

Time:06-12

See the code below or the corresponding playground:

type SomeType = {
  [P in 'u']?: string;
} & {
  [P in 'a' | 'b' | 'c' | 'd']?: SomeType;
}

const st: SomeType = {
  u: '1',
  a: {
    u: '2',
    b: {
      u: '3',
      c: {
        d: {
        },
        e: 1, // why doesn't this cause an error here? oO thank you!
      }
    },
  },
  e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
};

I don't know what else to say here. If you comment out the last e: 1 then no ts error is generated. Why?

Edit: OK, like wtf.

type SomeType = {
  u?: string;
  a?: SomeType;
  b?: SomeType;
  c?: SomeType;
  d?: SomeType;
}

const st: SomeType = {
  u: '1',
  a: {
    u: '2',
    b: {
      u: '3',
      c: {
        d: {
        },
        e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
      }
    },
  },
  e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
};

Edit: Here is the fixed version I created with the advice from @tokland that recursion with intersection is broken.

type P = 'u';
type Q = 'a' | 'b' | 'c' | 'd';

type SomeType = {
  [K in (P | Q)]?: K extends P
    ? string
    : SomeType
};

const st: SomeType = {
  u: '1',
  a: {
    u: '2',
    b: {
      u: '3',
      c: {
        d: {
        },
        e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
      }
    },
  },
  e: 1, // expected error: Object literal may only specify known properties, and 'e' does not exist in type 'SomeType'.
};

CodePudding user response:

It's a known bug, excess property check for nested type intersections worked fine up until 3.8:

https://github.com/microsoft/TypeScript/issues/47935

3.8: working

3.9: not working

  • Related