输入工厂函数
Typing a factory function
我有一个运行时构建的函数列表,这些函数用参数初始化,return 不同的东西:
mythings: [
param => ({foo: param, bar: 2}),
param => ({baz: param, qux: 4}),
]
现在我想写一个工厂函数来创建这些东西的一个子集,比如:
const createThings = (things) => things.map(thing => thing("param"));
我正在努力输入工厂功能。我最近的尝试是这样的:
// MyCreator?
const createThings = <T>(things: MyCreator<T>[]) =>
things.map(thing => thing("param"));
但是这种尝试并没有奏效。有什么想法吗?
您可以使用映射 array/tuples 从数组中的每个项目中提取 return 类型:
const mythings = [
(param: string) => ({foo: param, bar: 2}),
(param: string) => ({baz: param, qux: 4}),
]
type AllReturnTypes<T extends Array<(...a: any[])=> any>> = {
[P in keyof T]: T[P] extends (...a: any[])=> infer R?R:never
}
const createThings = <T extends Array<(...a: any[])=> any>>(things: T): AllReturnTypes<T> =>
things.map(thing => thing("param") )as any; // assertion necessary unfortunately
createThings(mythings) // ({ foo: string; bar: number; } | { baz: string; qux: number; })[]
您还可以将 myThings
设为元组类型,以便为结果中的每个索引获得更准确的类型:
function tuple<T extends any[]>(...a: T) {
return a;
}
const mythings = tuple(
(param: string) => ({ foo: param, bar: 2 }),
(param: string) => ({ baz: param, qux: 4 }),
)
let r = createThings(mythings) // [{ foo: string; bar: number; }, { baz: string; qux: number; }
或者在 typescript 3.4 中你可以使用 as const
:
const mythings = [
(param: string) => ({ foo: param, bar: 2 }),
(param: string) => ({ baz: param, qux: 4 }),
] as const
我有一个运行时构建的函数列表,这些函数用参数初始化,return 不同的东西:
mythings: [
param => ({foo: param, bar: 2}),
param => ({baz: param, qux: 4}),
]
现在我想写一个工厂函数来创建这些东西的一个子集,比如:
const createThings = (things) => things.map(thing => thing("param"));
我正在努力输入工厂功能。我最近的尝试是这样的:
// MyCreator?
const createThings = <T>(things: MyCreator<T>[]) =>
things.map(thing => thing("param"));
但是这种尝试并没有奏效。有什么想法吗?
您可以使用映射 array/tuples 从数组中的每个项目中提取 return 类型:
const mythings = [
(param: string) => ({foo: param, bar: 2}),
(param: string) => ({baz: param, qux: 4}),
]
type AllReturnTypes<T extends Array<(...a: any[])=> any>> = {
[P in keyof T]: T[P] extends (...a: any[])=> infer R?R:never
}
const createThings = <T extends Array<(...a: any[])=> any>>(things: T): AllReturnTypes<T> =>
things.map(thing => thing("param") )as any; // assertion necessary unfortunately
createThings(mythings) // ({ foo: string; bar: number; } | { baz: string; qux: number; })[]
您还可以将 myThings
设为元组类型,以便为结果中的每个索引获得更准确的类型:
function tuple<T extends any[]>(...a: T) {
return a;
}
const mythings = tuple(
(param: string) => ({ foo: param, bar: 2 }),
(param: string) => ({ baz: param, qux: 4 }),
)
let r = createThings(mythings) // [{ foo: string; bar: number; }, { baz: string; qux: number; }
或者在 typescript 3.4 中你可以使用 as const
:
const mythings = [
(param: string) => ({ foo: param, bar: 2 }),
(param: string) => ({ baz: param, qux: 4 }),
] as const