typescript - 如何键入检查名义类型的 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'.
那么为什么会失败呢?当然 anX
应该总是可以分配给X | undefined
?
解决方案
我认为自从编写代码以来,打字稿已经改变了它处理空的联合和交叉点(或它认为是空类型)的方式。我无法找到改变行为的 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' })
推荐阅读
- python - python concurrent.futures线程与进程问题
- python - 大熊猫中棘手的级联分组
- apache-nifi - 在单个 Nifi 流中加载具有不同列的输入文件
- html - Html Bootstrap列堆叠不并排
- python - alembic 升级为 heroku 版本
- oracle - 在 MacOS High Sierra 上使用 SQL Developer 连接到 Oracle 时出现网络适配器错误
- android - android中的Picker问题(所选项目的文本)
- kubernetes - Operator 获取 Deployment 配置的最佳实践
- excel - 如何在 Excel 中舍入小数列表,以使整数之和等于定义的总数?
- python - 如何在 Windows 上捕捉 PyCharm 中的停止按钮?