На вопрос я спросил, почему ниже фрагмент не скомпилируется
type User = { id: number; kind: string; }; function makeCustomer(u: T): T { // Below error, why? return { id: u.id, kind: 'customer' } }
На первый взгляд объект, который возвращается Makecustomer
действительно Пользователь
Тип, так как он имеет оба необходимых поля, определенные в Пользователь
Отказ Решающая вещь, чтобы понять, что мы работаем здесь с переменной типа T
который простирается от Пользователь
Но это не значит, что это Пользователь
. T
назначается Пользователь
Так что он должен иметь все поля, которые Пользователь
Есть, но у него могут быть больше полей!
Да, и это именно проблема, возвращенный объект – это Пользователь
и пройти все ограничения этого, но не проходят все ограничения T
которые могут иметь дополнительные поля. Мы не знаем, что такое эти поля, поэтому для того, чтобы исправить набрать, мы должны сделать объект, который имеет все поля T
и мы знаем все поля T
находятся в аргументе u
. Затем мы можем использовать оператор SPRECT, чтобы распространять все неизвестные поля на вновь созданный объект.
function makeCustomer(u: T): T { // no error return { ...u, // spread all properties of u being T id: u.id, // yes redundant line, leaving it for consistency kind: 'customer' } }
Теперь мы уверены, что все поля из T
будет включен в наш возвращенный объект. Но есть также случай, когда Typearcript имеет выпуск, выпуск дизайна, вероятно. Мы можем создать здесь ситуацию, которая будет просто ошибкой, когда значение не будет соответствовать типу. Подумайте, что мы можем сделать другой тип, который расширит Пользователь
, давайте скажем Админ
type Admin = User & { kind: 'admin'; }
Мы можем спросить, если Админ
простирается по-настоящему Пользователь
:
type IsAdminAUser = Admin extends User ? true : false // evaluates to true
Хорошо, так Админ
это Пользователь
тогда мы можем использовать Makecustomer
с Админ
? Смотрит, что мы должны как T продлевает пользователь
и Admin продлевает пользователь
Отказ Давайте проверим:
const admin = makeCustomer({ id: 1, kind: 'admin' } as Admin)
И есть ошибка, TS говорит Админ
имеет тип Админ
Но когда мы консоль. Пожалуйста, структура – это {ID: 1, вид: «Клиент»}
, к сожалению, мы добрались до ситуации, где TS имеет неверные предположения 😩.
Весь код можно найти в игровая площадка
Эта серия только начинается Отказ Если вы хотите знать о новых захватывающих вопросах из продвинутых TeampScript, пожалуйста, следуйте за мной на dev.to и Twitter Отказ
Оригинал: “https://dev.to/macsikora/advanced-typescript-exercises-answer-2-2ihh”