TypeScript:基于泛型的可选属性定义问题
解决TypeScript泛型条件下可选/必填字段的问题
你需要通过条件类型区分泛型参数R的不同场景,实现「默认时registry可省略,指定非undefined的R时必须必填」的需求。修改后的类型定义如下:
export type MyConfig< T extends MyObject = MyObject, R extends MyRegistry | undefined = undefined, > = { title: string | null, objects: T[], } & (R extends undefined ? { registry?: undefined } : { registry: R } );
验证各场景:
- 示例a(默认泛型):
const a: MyConfig = { title: null, objects: [] };正常通过,此时registry属于可选的undefined类型,可直接省略。 - 示例b(指定R为MyRegistry):
const b: MyConfig<MyObject, MyRegistry> = { title: null, objects: [], registry: {} };正常工作,此时registry是必填的MyRegistry类型,不填会触发报错。 - 示例c(指定R为undefined):
const c: MyConfig<MyObject, undefined> = { title: null, objects: [], registry: undefined };正常工作,也可以直接省略registry字段。 - 示例d(指定R为MyRegistry|undefined):
const d: MyConfig<MyObject, MyRegistry|undefined> = { title: null, objects: [], registry: undefined };正常工作,此时registry可填MyRegistry类型值、undefined,或直接省略。
原理说明:
通过交叉类型&结合条件判断R extends undefined,动态生成字段约束:
- 当
R为默认的undefined时,合并{ registry?: undefined },允许省略registry(省略时等同于赋值undefined)。 - 当
R为MyRegistry或MyRegistry|undefined这类非纯undefined类型时,合并{ registry: R },强制要求必须提供registry字段且类型符合R的约束。
这种写法完美兼顾了默认场景的可选性和指定泛型后的必填性,解决了你之前遇到的矛盾问题。
内容的提问来源于stack exchange,提问作者Max Cruer
相关产品推荐
相关产品推荐

