如何键入检查名义类型的ID
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何键入检查名义类型的ID相关的知识,希望对你有一定的参考价值。
我正在尝试这里描述的基于枚举的名义输入方法: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
?
答案
我认为自从代码编写以来,typescript已经改变了处理联合和交叉与空(或它认为是空类型)的方式。我无法找到改变行为的PR但是如果我找到它会尝试发布它(我找不到PR但是在2.9中发生了中断)
对于品牌类型,compiler team使用的交集类型只包含一个额外成员而不是与枚举的交集:
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' })
以上是关于如何键入检查名义类型的ID的主要内容,如果未能解决你的问题,请参考以下文章