#typescript
Вопрос:
Я хочу определить интерфейс для общей строки таблицы, в основном это любой объект, ограниченный значениями атрибутов в качестве примитивных типов.
Но когда я пытаюсь назначить объекту определенного типа строку, это не удается. Почему? И как заставить это работать? Я хочу обеспечить, чтобы строки могли быть только объектами с примитивными значениями атрибутов.
// Table row
export type Row = Record<string, string | number | undefined>
// User
interface User { name: string }
const jim: User = { name: 'Jim' }
const row: Row = jim // <== Error
Ошибка
Type 'User' is not assignable to type 'Row'.
Index signature for type 'string' is missing in type 'User'.
Ответ №1:
Интерфейсы могут быть расширены. Без ограничения типа индекса объект, расширяющий пользователя, который может храниться в переменной, введенной пользователем, может иметь другие свойства.
// User
interface User { name: string }
interface FooUser extends User { foo(): void; }
const jim: FooUser = { name: 'Jim', foo() {} }
const jimAsUser: User = jim;
const row: Row = jim; // fails as it should:
// foo is not a string, number, or undefined!
Обратите внимание , что если вы используете type
вместо interface
этого, это безопаснее: дополнительные свойства в подинтерфейсах не ожидаются. Тем не менее, Машинопись позволяет это, хотя и не должна. type
и interface
есть некоторые тонкие детали, на которые ссылается руководство по машинописи (хотя и не вдаваясь в этот конкретный случай).
// UserAsType
type UserAsType = { name: string };
const jimAsType: UserAsType = { name: 'Jim' }
const jimAsTypeFromFooUser: UserAsType = jim; // this *should* fail
const row2: Row = jimAsType