如何定义含完整额外属性或无额外属性的TypeScript类型?
解决TypeScript类型二选一约束问题
你需要的是要么包含isLocked+所有必填的AccountMetadata属性,要么仅包含isLocked属性,且不允许额外未定义属性。先分析你两种写法的问题:
- 第一种用
{}的问题:TS中{}代表任意非null/undefined的对象,会允许像{ isLocked: true, extraProp: 'foo' }这类不符合预期的结构,无法限制额外属性。 - 第二种用
never的问题:{ isLocked: boolean } & never会直接被简化为never,最终类型只剩带AccountMetadata的分支,丢失了仅含isLocked的情况。
正确写法
可以通过限制额外属性必须不存在来实现需求,有两种简洁的写法:
写法1:直接联合明确分支
type AccountMetadata = { roles: string[]; name: string; } type Account = | { isLocked: boolean } & AccountMetadata | { isLocked: boolean; [K in keyof AccountMetadata]?: never };
写法2:交叉联合类型(更紧凑)
type AccountMetadata = { roles: string[]; name: string; } type Account = { isLocked: boolean } & ( AccountMetadata | { [K in keyof AccountMetadata]?: never } );
原理说明
第二个分支中的{ [K in keyof AccountMetadata]?: never }是关键:它将AccountMetadata的所有属性设为可选的never类型,意味着这些属性要么完全不存在,要么只能被赋值为never(实际无法赋值),从而严格保证该分支仅含isLocked属性,没有额外内容。
最终生成的类型完全符合你的期望:
{ isLocked: boolean; roles: string[]; name: string } | { isLocked: boolean }
内容的提问来源于stack exchange,提问作者LazioTibijczyk
相关产品推荐
相关产品推荐

