首页 > 解决方案 > 将参数类型作为类型参数传递给 TypeScript 或 Flow 中的另一种类型

问题描述

出于演示目的,请考虑以下类型:

type ToEnglish<A extends string> = 
  A extends "1" ? "one" :
  A extends "2" ? "two" :
  A extends "3" ? "three" :
  "etc";

type Convert<A extends string> =
  A extends `${infer C}${infer Tail}` ? 
    `${ToEnglish<C>}-${Convert<Tail>}` : "";

例如,Convert<"12">结果为"one-two-".

现在我想让它更通用,并接受上面的“翻译器”ToEnglish作为参数:

type Convert2<A extends string, Translator> =
  A extends `${infer C}${infer Tail}` ? 
    `${Translator<C>}-${Convert<Tail>}` : "";

这不起作用:Type 'Translator' is not generic. ts(2315)

如果我尝试写:

type Convert3<A extends string, Translator<_>> = 

我得到:',' expected. ts(1005)<_>.

:有没有办法在 TypeScript、Flow 或另一个 JavaScript 超集中以某种方式将参数(通用)类型作为参数(参数)传递给另一种类型?
类似于高阶函数,但针对类型。

标签: typescriptflowtypetypescript-genericshigher-kinded-typeshigher-order-types

解决方案


我建议一个解决方案,绕过必须直接将泛型类型作为类型参数传递。例如,通过使用本质上是翻译者的记录,您可以改为传递给定翻译者的名称并访问类型:

操场

type ToEnglish<A extends string> = 
  A extends "1" ? "one" :
  A extends "2" ? "two" :
  A extends "3" ? "three" :
  "etc";

type ToSpanish<A extends string> = 
  A extends "1" ? "uno" :
  A extends "2" ? "dos" :
  A extends "3" ? "tres" :
  "etc";


type TranslatorMap<A extends string> = {
    English: ToEnglish<A>;
    Spanish: ToSpanish<A>;
}

type ConvertGeneric<A extends string, Translator extends keyof TranslatorMap<A>> =
  A extends `${infer C}${infer Tail}` ? 
    `${TranslatorMap<C>[Translator]}-${ConvertGeneric<Tail, Translator>}` : "";

type EnglishTest = ConvertGeneric<"12", "English">
type SpanishTest = ConvertGeneric<"12", "Spanish">



推荐阅读