Когда тип строкового литерала определен в интерфейсе, я получаю неожиданное поведение.
interface IFoo {
value: 'foo' | 'boo';
}
Когда я реализую интерфейс в классе, я получаю ошибку:
class Foo implements IFoo {
value = 'foo';
}
Я получаю ошибку: Свойство 'Значение 'в типе' Foo 'нельзя назначить одному и тому же свойству в базовом типе' IFoo '.Но 'foo' является правильным значением для строкового литерала.
С другой стороны:
class Boo implements IFoo {
value;
constructor() {
this.value = 'foo';
this.value = 'boo';
this.value = 'koo'; // must be an error Boo doesn't implement IFoo
}
}
const test = new Boo();
test.value = 'koo';
Этот код не вызывает ошибок, но Boo.value
имеет тип any
,Я ожидал получить ошибку, что Boo не реализует IFoo, но ошибки нет.
Единственный правильный способ, который я обнаружил, - реализовать классы таким образом:
class Koo implements IFoo {
value: 'foo' | 'boo' = 'foo';
}
Итак, мне пришлось объявить 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;
Я понимаю, что это случилось, потому что компилятор ts получил тип Doo.value из назначенного значения в объявлении поля.Похоже, бесполезно объявлять поля строковых литералов в интерфейсах, или я делаю что-то не так.А также выяснил, что классы могут реализовывать интерфейсы с типом for для любых типов, так что дело за разработчиком.