简化打字模式的重复使用

时间:2019-06-20 18:43:42

标签: typescript typescript-typings

我有以下两个界面:

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中重用它们吗?

1 个答案:

答案 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"'.

然后使用:

{