如何获取TypeScript类属性的Getter/Setter类型?
提取类属性Getter与Setter的独立类型(TypeScript)
自TypeScript 4.3版本起,类的属性允许为getter和setter设置不同的类型,但目前没有原生工具能直接提取这两个独立的类型。问题在于类属性会被视为普通变量类型,无法直接区分是否包含getter或setter;而原生的Parameters<I>和ReturnType<I>仅适用于函数/方法,无法处理访问器属性。
我们期望实现这样的效果:
当类同时包含getter和setter时:
class Foo { get bar(): number { /** ... */ } set bar(baz: string) { /** ... */ } } type GetterOfFooBar = GetterOf<typeof Foo.prototype.bar>; // number type SetterOfFooBar = SetterOf<typeof Foo.prototype.bar>; // string
当类仅包含getter时:
class Foo { get bar(): number { /** ... */ } } type GetterOfFooBar = GetterOf<typeof Foo.prototype.bar>; // number type SetterOfFooBar = SetterOf<typeof Foo.prototype.bar>; // never
实现思路与代码
需要注意的是,直接取typeof Foo.prototype.bar得到的是getter的返回类型(上例中的number),无法直接从中获取setter的类型。因此更可靠的方式是传入类的类型和属性名来提取:
// 提取指定类属性的getter返回类型 type GetterOf<T, K extends keyof T> = T[K] extends { get(): infer R } ? R : never; // 提取指定类属性的setter参数类型,不存在setter时返回never type SetterOf<T, K extends keyof T> = T[K] extends { set(v: infer V): void } ? V : never;
使用示例:
class Foo { get bar(): number { return 1; } set bar(baz: string) {} } // 获取bar属性的getter返回类型 type BarGetter = GetterOf<Foo, 'bar'>; // number // 获取bar属性的setter参数类型 type BarSetter = SetterOf<Foo, 'bar'>; // string class OnlyGetterFoo { get bar(): number { return 2; } } type OnlyGetterBar = GetterOf<OnlyGetterFoo, 'bar'>; // number type OnlySetterBar = SetterOf<OnlyGetterFoo, 'bar'>; // never
如果一定要贴近你期望的GetterOf<typeof Foo.prototype.bar>写法,可以结合泛型推断,但这种方式无法获取setter类型(因为属性类型本身不包含setter信息):
type GetterOf<T> = T; type SetterOf<T> = T extends { set(v: infer V): void } ? V : never;
不过这种写法仅能在特殊场景下生效,更推荐使用前面基于类类型+属性名的实现方案。
内容的提问来源于stack exchange,提问作者Ratibus11
相关产品推荐
相关产品推荐

