我有以下两个界面:
export interface Converter<T> {
decode?: Decoder<T>;
encode?: Encoder<T>;
notify?: Notifier<T>;
type?: T;
}
export interface Api {
state: Converter<State>;
water: Converter<Water>;
version: Converter<Versions>;
}
在许多函数中,我要么要确保返回值是基于传递给函数的参数的泛型,例如
get<Name extends keyof Api, Value = Api[Name]["type"]>(
name: Name
): Value {
// ...
}
这意味着如果我调用get("state")
,则返回值将是State
类型;如果我调用get("water")
,则返回值将是Water
类型。
当我有多个参数时,我也会使用它:
set<Name extends keyof Api, Value = Api[Name]["type"]>(
name: Name,
value: Value
): void {
// ...
}
value
的类型取决于name
。但是我必须写相同的模式:
<Name extends keyof Api, Value = Api[Name]["type"]>
再次。我可以一次定义这些类型并在TypeScript中重用它们吗?
答案 0 :(得分:1)
您不能一次定义它们,因为它们在很大程度上取决于函数中的type参数,但是可以使用一些别名来清理周围的一些样板。
type ApiKey = keyof Api;
type ApiValue<Name extends ApiKey> = Api[Name]["type"];
我们无法绕过Name
类型的参数,但是如果只希望将Value
作为默认参数并使用一次,则不必使用class X {
get<Name extends ApiKey>(name: Name): ApiValue<Name> {
return ...;
}
}
。
new X().get('state') // State
new X().get('unknown') // Argument of type '"unknown"' is not assignable to parameter
// of type '"state" | "water" | "version"'.
然后使用:
{