如何在get和set类型不同的类型中推断set访问器类型?
解决TypeScript中提取get/set访问器类型的问题
我们需要实现InferGetSet类型,从包含get/set访问器的类型中分别提取get的返回类型和set的参数类型。以如下目标类型为例:
type B = { get value(): number set value(v: string); }
期望InferGetSet<B>的结果是{ get: number, set: string },但常规的条件类型推断会失败:
失败的尝试
尝试1:同时匹配get和set
type Fail1<B> = B extends { get value(): infer G, set value(v: infer S) } ? { get: G, set: S } : never type f1 = Fail1<B> // { get: number, set: unknown } - 失败
原因:TypeScript在单个条件类型中同时匹配get和set时,无法正确区分两者的类型约束,导致set的参数类型被推断为unknown。
尝试2:分开匹配get和set
type Fail2<B> = { get: B extends { get value(): infer V } ? V : never, set: B extends { set value(v: infer V) } ? V : never, } type f2 = Fail2<B> // { get: number, set: number } - 失败
原因:单独匹配set访问器时,TypeScript会隐式将get的返回类型与set的参数类型做兼容推断,错误地将set的参数类型推断为get的返回类型。
正确实现方式
方式一:利用返回值和参数类型提取
通过ReturnType提取get访问器的返回类型,Parameters提取set访问器的参数类型:
type InferGetSet<T> = { get: ReturnType<T['value']>; set: Parameters<T['value']>[0]; } type Result = InferGetSet<B>; // { get: number, set: string }
方式二:精准匹配set访问器的函数类型
明确将set访问器匹配为函数类型,避免被get类型干扰:
type InferGetSet<T> = { get: T extends { get value(): infer G } ? G : never; set: T extends { set value: (v: infer S) => void } ? S : never; } type Result = InferGetSet<B>; // { get: number, set: string }
内容的提问来源于stack exchange,提问作者Dimava
相关产品推荐
相关产品推荐

