When defining a string literal type in an interface, I encountered unexpected behaviors.
interface IFoo {
value: 'foo' | 'boo';
}
Upon implementation of the interface in a class, I encountered an error:
class Foo implements IFoo {
value = 'foo';
}
The error message states: Property 'value' in type 'Foo' is not assignable to the same property in base type 'IFoo'. However, 'foo' is a correct value for the string literal.
On the other hand:
class Boo implements IFoo {
value;
constructor() {
this.value = 'foo';
this.value = 'boo';
this.value = 'koo'; // Must result in an error as Boo does not fully implement IFoo
}
}
const test = new Boo();
test.value = 'koo';
This code does not produce any errors, but the Boo.value
is of type any
. I had expected to receive an error indicating that Boo does not fully implement IFoo, but no error occurred.
The only correct way I found is to implement classes like this:
class Koo implements IFoo {
value: 'foo' | 'boo' = 'foo';
}
Therefore, I resorted to declaring an enum:
enum Doos { foo = 'foo', boo = 'boo' }
interface IDoo {
value: Doos;
}
class Doo implements IDoo {
value = Doos.foo;
}
const test = new Doo();
test.value = Doos.boo;
I realized that this occurred because the TypeScript compiler inferred the type of Doo.value from the assigned value in the field declaration. It seems unnecessary to declare fields of string literal types in interfaces, or perhaps I am making a mistake. Additionally, I discovered that classes can implement interfaces with fields of type any, leaving it up to the developer.