根据变量输入键入回调函数
Typing callback functions based on variable inputs
采用以下代码(诚然是一个人为的例子):
arbitraryFunction(
// Dynamically generated input
[
returnValue("key1", "a"),
returnValue("key2", 1),
returnValue("key3", ()=>{})
],
// Callback, parameters are typed against input
(value : {key1: string, key2: number, key3: Function} )=>{
return value
}
)
我希望在回调中键入 value
参数以引用给定的输入。
例如,这个回调函数将被拒绝:
// key1's type is string, not number!
(value : {key1: number} )=>{}
我尝试过使用泛型,但它似乎不起作用。有人知道这是否可行吗?
是的 - 这是可以做到的。您需要在泛型中使用递归数组迭代来遍历 ReturnValues 数组以构建回调参数。
如果您需要进一步解释,请告诉我,因为这里有很多内容!
function returnValue<K extends string, T>(key: K, type: T): [K, T] {
return [key, type];
}
type ReturnValue = ReturnType<typeof returnValue>;
type GenerateCallbackParams<I extends readonly ReturnValue[], P = {}> =
// Base case where we have one item left in I
I extends readonly [infer R]
? R extends [infer K, infer T]
? K extends string
// Merge params with K: T
? P & { [key in K]: T }
: P
: never
// When multiple array elements in I
: I extends readonly [infer R, ...(infer Tail)]
? R extends [infer K, infer T]
? K extends string
? Tail extends ReturnValue[]
? GenerateCallbackParams<Tail, P & { [key in K]: T }>
: never
: never
: never
: never;
function arbitraryFunction<I extends readonly ReturnValue[]>(inputParams: I, callback: (params: GenerateCallbackParams<I>) => GenerateCallbackParams<I>) {
}
// Has to be declared as const here otherwise TS widens the type inside the array
const params = [
returnValue("key1", "a"),
returnValue("key2", 1),
returnValue("key3", ()=>{})
] as const;
arbitraryFunction(
// Dynamically generated input
params,
// Callback, parameters are typed against input
({ key1, key2, key3}) => {
typeof key1; // string
typeof key2; // number
typeof key3; // () => void
return { key1, key2, key3 };
}
)
采用以下代码(诚然是一个人为的例子):
arbitraryFunction(
// Dynamically generated input
[
returnValue("key1", "a"),
returnValue("key2", 1),
returnValue("key3", ()=>{})
],
// Callback, parameters are typed against input
(value : {key1: string, key2: number, key3: Function} )=>{
return value
}
)
我希望在回调中键入 value
参数以引用给定的输入。
例如,这个回调函数将被拒绝:
// key1's type is string, not number!
(value : {key1: number} )=>{}
我尝试过使用泛型,但它似乎不起作用。有人知道这是否可行吗?
是的 - 这是可以做到的。您需要在泛型中使用递归数组迭代来遍历 ReturnValues 数组以构建回调参数。
如果您需要进一步解释,请告诉我,因为这里有很多内容!
function returnValue<K extends string, T>(key: K, type: T): [K, T] {
return [key, type];
}
type ReturnValue = ReturnType<typeof returnValue>;
type GenerateCallbackParams<I extends readonly ReturnValue[], P = {}> =
// Base case where we have one item left in I
I extends readonly [infer R]
? R extends [infer K, infer T]
? K extends string
// Merge params with K: T
? P & { [key in K]: T }
: P
: never
// When multiple array elements in I
: I extends readonly [infer R, ...(infer Tail)]
? R extends [infer K, infer T]
? K extends string
? Tail extends ReturnValue[]
? GenerateCallbackParams<Tail, P & { [key in K]: T }>
: never
: never
: never
: never;
function arbitraryFunction<I extends readonly ReturnValue[]>(inputParams: I, callback: (params: GenerateCallbackParams<I>) => GenerateCallbackParams<I>) {
}
// Has to be declared as const here otherwise TS widens the type inside the array
const params = [
returnValue("key1", "a"),
returnValue("key2", 1),
returnValue("key3", ()=>{})
] as const;
arbitraryFunction(
// Dynamically generated input
params,
// Callback, parameters are typed against input
({ key1, key2, key3}) => {
typeof key1; // string
typeof key2; // number
typeof key3; // () => void
return { key1, key2, key3 };
}
)