Как печатать чеки именных идентификаторов - PullRequest
0 голосов
/ 17 декабря 2018

Я пробую описанный здесь метод номинальной типизации на основе перечисления: https://basarat.gitbooks.io/typescript/docs/tips/nominalTyping.html

enum PersonIdBrand {}
export type PersonId = PersonIdBrand & string

interface Person {
  id: PersonId
  firstName: string
  lastName: string
}

Я столкнулся с проблемой добавления типов в некоторые фабричные методы, используемые тестами.Эти вспомогательные методы позволяют создавать тестовые данные со значениями по умолчанию, которые можно выборочно переопределять:

const makeTestPerson = ({
  id = 'personId' as PersonId,
  firstName = 'Bob',
  lastName = 'Smith'
}: Partial<Person> = {}): Person => ({
  id,
  firstName,
  lastName
})

const person = makeTestPerson({ lastName: 'Ross' })

Однако tsc выдает ошибку:

error TS2322: Type 'PersonId' is not assignable to type 'never'.

11   id = 'personId' as PersonId,

Если я вместо этого использую id: stringвместо этого он компилируется без проблем.Можно ли как-нибудь проверить эти функции с помощью PersonId?


Обновление , изучив немного больше, думаю, есть более фундаментальная проблема с этой стратегией:

const maybePersonId: PersonId | undefined = ("personId" as PersonId)

Это также не с:

TS2322: Type 'PersonId' is not assignable to type 'undefined'.

Так почему же это не удается?Конечно, X всегда должен быть назначен на X | undefined?

1 Ответ

0 голосов
/ 17 декабря 2018

Я думаю, что с тех пор, как этот код был написан, машинопись изменила способ обработки союзов и пересечений с пустым (или то, что он воспринимает как пустой тип).Я не могу найти PR, который меняет поведение, но я постараюсь опубликовать его, если найду его (я не могу найти PR, но разрыв происходит в 2.9)

Для фирменных типов команда компилятора использует пересечение с типом, который содержит только один дополнительный элемент, а не пересечение с перечислением:

export type Path = string & { __pathBrand: any };

Я бы просто пошел с таким подходом:

export type PersonId = { __personIdBran: any } & string

interface Person {
  id: PersonId
  firstName: string
  lastName: string
}

const makeTestPerson = ({
  id = 'personId' as PersonId,
  firstName = 'Bob',
  lastName = 'Smith'
}: Partial<Person> = {}): Person => ({
  id,
  firstName,
  lastName
})

const person = makeTestPerson({ lastName: 'Ross' })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...