#typescript
Вопрос:
Я использую Omit
тип утилиты для удаления description
in TodoPreview
, но при назначении переменной типа TodoPreview
другому типу Todo
пропущенное поле все еще присутствует и не попадает во время компиляции. Есть ли способ избавиться от пропущенного поля только в todo2:TodoPreview
объявлении типа?
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
type TodoPreview = Omit<Todo, "description">;
const todo: Todo = {
title: "Clean room",
completed: false,
createdAt: 1615544252770,
description: "Test",
};
const todo2: TodoPreview = {
...todo
}
//Same result with `const todo2: TodoPreview = todo;`
console.log(todo2);
Поскольку это невозможно перехватить во время компиляции, при description
наличии поля будет получен следующий результат:
{
"title": "Clean room",
"completed": false,
"createdAt": 1615544252770,
"description": "Test"
}
Ответ №1:
Это ожидаемое поведение, поскольку объекты в typescript считаются несколько открытыми для расширения с дополнительными полями. Единственные места, где дополнительные поля могут сделать типы несовместимыми, — это те, где происходит проверка избыточных свойств. И ваше дело не из их числа.
Хотя вы не можете назначить объектный литерал extra
полям, вы можете свободно назначить то же значение, которое ранее было присвоено переменной
type A = {
s: string
}
const bad: A = { s: '', n: 2 } // excess property check
let _good = { s: '', n: 2}
const good: A = _good // no error
Чтобы явно запретить description
поле в исходном объекте, необходимо сделать тип description
поля явно не назначаемым:
type TodoPreview = Omit<Todo, "description"> amp; { description?: never };