Why can I not have a generic interface WITH an optional property of a known type?

Advertisements
interface Thing {
  [ index: string ]: string | number | boolean | Thing | Array<string | number | boolean>
}

interface FooBarable extends Omit<Thing, 'foo' | 'bar'> {
  foo: string;
  bar?: string;
}

const x: FooBarable = { abc: 123, bool: true, foo: 'abc' };

gives me:

Property 'bar' of type 'string | undefined' is not assignable to 'string' index type 'string | number | boolean | Thing | (string | number | boolean)[]'.

Playground

Is there a way to make this work?

>Solution :

Try using a type intersection rather than inheritance.

interface Thing {
  [ index: string ]: string | number | boolean | Thing | Array<string | number | boolean>
}

type FooBarable = Thing & {
  foo: string;
  bar?: string;
}

const x: FooBarable = { abc: 123, bool: true, foo: 'abc' };

console.log(x);

Playground link

This is subtle, because type and interface are mostly the same, and interfaces are usually preferred, but this is one case where a type intersection is closer to what you want. (I believe that’s a similar issue to what’s described here.)

Leave a ReplyCancel reply