可以在function-overloads的帮助下实现。
首先,让我们定义callbackFn:
type CallbackFn<T> = T extends string ? "string !" : "not string!";
function callbackFn<T>(entry: T): CallbackFn<T>
function callbackFn<T>(entry: T) {
return typeof entry === 'string' ? "string !" : "not string!"
}
我重载了callbackFn 并使用CallbackFn 类型实用程序来推断返回类型。
现在,我们需要用于映射的类型实用程序。考虑一下:
type MapUtility<T extends ReadonlyArray<unknown>> = {
[Prop in keyof T]: CallbackFn<T[Prop]>
}
type Test1 = MapUtility<["foo", 42]> // ["string!", "not string!"]
既然所有的 utils 都设置好了,我们就可以编写我们的 main 函数了。请记住,没有必要使用as const 来推断文字参数。你可以使用variadic-tuple-types:
function map<
Elem,
Tuple extends Elem[]
>(tuple: [...Tuple]): MapUtility<Tuple>
function map(tuple: unknown[]) {
return tuple.map(callbackFn)
}
// ["string !", "not string!"]
const output = map(["foo", 42])
整个例子:
type CallbackFn<T> = T extends string ? "string !" : "not string!";
function callbackFn<T>(entry: T): CallbackFn<T>
function callbackFn<T>(entry: T) {
return typeof entry === 'string' ? "string !" : "not string!"
}
type MapUtility<T extends ReadonlyArray<unknown>> = {
[Prop in keyof T]: CallbackFn<T[Prop]>
}
type Test1 = MapUtility<["foo", 42]> // ["string!", "not string!"]
function map<
Elem,
Tuple extends Elem[]
>(tuple: [...Tuple]): MapUtility<Tuple>
function map(tuple: unknown[]) {
return tuple.map(callbackFn)
}
// ["string !", "not string!"]
const output = map(["foo", 42])
Playground
请记住,打字稿在map 之后不保留元组长度。见this答案。
This答案相关
附:如果您对 TypeScript 中的函数参数推断感兴趣,可以查看我的 article