TypeScript中如何基于类属性动态定义对象类型避免重复声明?
实现方案
你可以结合 TypeScript 内置工具类型 + 自定义属性过滤逻辑实现,无需重复声明属性类型,完整代码如下:
方案1:自动包含Foo类所有非方法属性
如果需要fallbacks自动同步Foo类的所有普通实例属性(排除类方法),可以用自定义过滤工具类型实现:
// 通用工具类型:过滤类型T中所有值为函数的属性,只保留普通属性 type PickNonFunctionProperties<T> = { [K in keyof T as T[K] extends Function ? never : K]: T[K] } // 直接从Foo类提取类型生成InitOptions type InitOptions = { fallbacks: PickNonFunctionProperties<InstanceType<typeof Foo>> }
方案2:仅包含指定的Foo类属性
如果只需要fallbacks包含指定属性(比如示例中只需要bar、baz,不需要bob),可以直接用内置Pick工具类型简化:
type InitOptions = { fallbacks: Pick<InstanceType<typeof Foo>, 'bar' | 'baz'> }
原理解释
typeof Foo:获取Foo类的构造函数类型,而非实例类型InstanceType<typeof Foo>:从构造函数类型中提取对应的类实例类型,等价于手动编写的{ bar: string; baz: number; bob: any; bad: () => boolean },不需要重复声明属性和对应类型- 自定义的
PickNonFunctionProperties利用了TypeScript 4.1及以上版本支持的键重映射语法,自动过滤掉bad这类函数类型的方法属性,避免把类方法也放到fallbacks配置中 - 如果需要指定属性,直接用
Pick选择对应的键即可,属性的类型会自动从Foo实例类型中继承,不需要手动重复写类型定义
内容的提问来源于stack exchange,提问作者Tyler Clendenin
相关产品推荐
相关产品推荐

