0

It's easier to explain this by looking at the actual code:

interface FooInterface {
  bar: (flags: { [key: string]: string }) => void;
}

export class Foo implements FooInterface {
  bar(flags: { myFlag: string }) {}
}

I want anyone who implements FooInterface.bar to pass an object. I don't care about the keys.

However, when I implemented it in Foo class and I named the key as myFlag I got an error that this key doesn't exist in the interface. See the complete error below.

How do I tell Typescript to ignore the keys in the implemented classes?

The error I got:

src/extensions/test/test.provider.ts:24:3 - error TS2416: Property 'bar' in type 'Foo' is not assignable to the same property in base type 'FooInterface'.
  Type '(flags: { myFlag: string; }) => void' is not assignable to type '(flags: { [key: string]: string; }) => void'.
    Types of parameters 'flags' and 'flags' are incompatible.
      Property 'myFlag' is missing in type '{ [key: string]: string; }' but required in type '{ myFlag: string; }'.

24   bar(flags: { myFlag: string }) {}
     ~~~

2 Answers 2

1

Using generic typings, you can force the flags to be an object with string values, then specify the type in the class implementation:

interface FooInterface<T extends { [key: string]: string }> {
  bar: (flags: T) => void;
}

type BarFlags = { myFlag: string };

export class Foo implements FooInterface<BarFlags> {
  bar(flags: BarFlags) {}
}

Playground Link

Sign up to request clarification or add additional context in comments.

Comments

1

The problem is that you are saying myFlag must be a string, but the type { [key: string]: string } does not guarantee that the myflag key actually exists. So it cannot satisfy the string type.

If you make the myFlag key optional it works, you then just have to check it for existence.

interface FooInterface {
  bar: (flags: { [key: string]: string }) => void;
}

export class Foo implements FooInterface {
  bar(flags: { myFlag?: string }) {
    if (flags.myFlag) {
      console.log(flags.myFlag) // logs a string
    }
  }
}

Playground


If you want to enforce that myFlag is provided when you call bar is the Foo class, then @leonardfactory's answer is what you need.

1 Comment

Thanks. I'm probably going to use both approaches yours and @leonardfactory depends on the circumstances. (so no idea whom I should mark as accepted :/). The part that confuses me is that I was under the impression that an Interface can be general and the implementation can be more specific and that's not the case here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.