Машинопись: сопоставленный тип с модификаторами свойств исключения изменений

При использовании сопоставленного типа «Минус», похоже, удаляются модификаторы из свойств. Я думаю, что это вызвано типом исключения, но я не уверен, почему.

Я ожидал, что Минус просто удалит ключи U из T без изменения модификаторов свойств T.

type Minus<T, U> = { [P in Exclude<keyof T, keyof U>]: T[P] }
type Noop<T> = { [P in keyof T]: T[P] }

interface Student {
  readonly gpa: number
  hobby?: string
  name: string
}

interface Person {
  name: string
}

type Difference = Minus<Student, Person>
// type Difference = {
//   gpa: number; <-- Where did readonly go?
//   hobby: string | undefined; <-- Why is it no longer optional? It seems to have picked up '| undefined' though...
// }

const test1: Difference = { gpa: 4 } // <-- Error: property 'hobby' is missing

type NoopType = Noop<Student>
// type StringsOnly = {
//   readonly gpa: number;
//   hobby?: string | undefined;
//   name: string;
// }

const test2: NoopType = { gpa: 4, name: "bob" } // OK

person Lionel Tay    schedule 29.07.2018    source источник


Ответы (1)


TypeScript будет сохранять модификаторы для гомоморфных отображаемых типов, как описано здесь, но основная идея заключается в том, что модификаторы сохраняются, если тип имеет вид { [P in keyof T]: T[P] } или что-то подобное. В вашем случае компилятор не распознает отображаемый тип как гомоморфный из-за Exclude<keyof T, keyof U>, и я почти уверен, что это ограничение где-то задокументировано, но я не могу найти его в данный момент. Простой способ обойти это - использовать дополнительное косвенное обращение через Pick, например: +

type Minus<T, U> = Pick<T, Exclude<keyof T, keyof U>>
person Titian Cernicova-Dragomir    schedule 29.07.2018