将参数类型作为类型参数传递给 TypeScript 或 Flow 中的另一种类型
Pass parametric type as a type argument to another type in TypeScript or 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)
在 <_>
。
Q:
有没有办法在 TypeScript、Flow 或另一个 JavaScript 超集中将参数(通用)类型作为参数(参数)以某种方式传递给另一种类型?
类似于高阶函数,但适用于类型。
我建议绕过必须将泛型类型直接作为类型参数传递的解决方案。例如,通过使用本质上是翻译者记录的内容,您可以改为传递给定翻译者的姓名并访问类型:
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">
这不是问题的直接答案。只是一个 flowjs
例子:
// @flow
type TypeConstructor = <V>() => {updated:V};
type Obj = {
a: number,
b: string
}
type Result = $ObjMap<Obj, TypeConstructor>
const ok:Result = {
a: {updated:42},
b: {updated:42}
}; // ok
const error:Result = {
a: 42,
b: 42
}; // error
您可能已经注意到,TypeConstructor
就像回调。
它检索一个 type
并将其转换为另一个 type
。每个 obj
key/value 对都传递给 TypeConstructor
。在 TypeScript 中不可能这样做,因为 TypeScript 需要 TypeConstructor
.
的显式泛型
出于演示目的,请考虑以下类型:
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)
在 <_>
。
Q:
有没有办法在 TypeScript、Flow 或另一个 JavaScript 超集中将参数(通用)类型作为参数(参数)以某种方式传递给另一种类型?
类似于高阶函数,但适用于类型。
我建议绕过必须将泛型类型直接作为类型参数传递的解决方案。例如,通过使用本质上是翻译者记录的内容,您可以改为传递给定翻译者的姓名并访问类型:
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">
这不是问题的直接答案。只是一个 flowjs
例子:
// @flow
type TypeConstructor = <V>() => {updated:V};
type Obj = {
a: number,
b: string
}
type Result = $ObjMap<Obj, TypeConstructor>
const ok:Result = {
a: {updated:42},
b: {updated:42}
}; // ok
const error:Result = {
a: 42,
b: 42
}; // error
您可能已经注意到,TypeConstructor
就像回调。
它检索一个 type
并将其转换为另一个 type
。每个 obj
key/value 对都传递给 TypeConstructor
。在 TypeScript 中不可能这样做,因为 TypeScript 需要 TypeConstructor
.