gpt4 book ai didi

typescript - Typescript 函数中的复杂签名

转载 作者:搜寻专家 更新时间:2023-10-30 21:19:28 24 4
gpt4 key购买 nike

以下泛型函数接受一个函数对象并返回一个具有相同 propnames 的对象,该对象的值与相应函数的返回值相同。

const combineValues = obj => { 
const res = {};
for (const k in obj){
res[k] = obj[k]()
}
return res;
}
const combined = combineValues({
n: () => 1,
s: () => 's'
}); // { n: 1, s: 's' }

尝试在 Typescript 中为此函数定义签名和实现

const combineValues =
<K extends string> (obj: Record<K, () => any>): Record < K, any > => {
const res = {} as Record<K, any>;
for (const k in obj){
res[k] = obj[k]()
}
return res;
}

const combined = combineValues({
n, s
}) // Record<"n" | "s", any>

但是 combined 不保留值的原始类型

const combcombineValues = <K extends string, T>(obj: Record<K, () => T>): Record<K, T> => {
const res = {} as Record<K, T>;
for (const k in obj){
res[k] = obj[k]()
}
return res;
}

仅当所有函数 props 返回相同类型 T 时才有效

是否可以在 Typescript 中完整定义它?

最佳答案

这可以在当前版本的 TypeScript (v2.7) 中完成,无需等待条件类型,方法是使用 inference from mapped types ,这是 TypeScript 的一项功能,其中函数可以从输出到输入似乎“向后”的方向推断类型。

首先让我们定义映射类型Funcs<T>它接受一个普通对象并将其转换为一个对象,该对象的属性都是返回普通对象属性类型的函数:

type Funcs<T> = { [K in keyof T]: (...args:any[]) => T[K] }

请注意这种类型基本上与您想要做的相反。现在让我们输入 combineValues() :

const combineValues = <T>(obj: Funcs<T>): T => {
const res = {} as T; // only change in body
for (const k in obj) {
res[k] = obj[k]()
}
return res;
}

如您所见,它需要一个 Funcs<T>作为输入并返回 T作为输出。让我们看看它是否有效:

const combined = combineValues({
n: () => 1,
s: () => 's'
}); // { n: number, s: string }

这就是几乎您想要的。唯一的区别是 TypeScript 倾向于解释 () => 1作为返回 number 的函数而不是返回文字 1 的函数.您可以采取一些措施来解决这个问题;最简单的(虽然有点重复)是断言返回类型文字:

const combined = combineValues({
n: () => 1 as 1,
s: () => 's' as 's'
}); // { n: 1, s: 's' }

希望对您有所帮助。祝你好运!

更新:注意到编译器似乎键入 combined作为{n: any, s: any}在 typescript 2.7 中。幸运的是,这似乎只有在您使用 Intellisense 检查类型时才会发生,正如(我认为)在 Microsoft/TypeScript#14041 中指出的那样.如果您实际使用该值,您会发现它具有正确的类型:

combined.n = 0 // error, 0 is not assignable to 1
combined.s = 0 // error, 0 is not assignable to 's'

Playground link

所以,我想我支持这个答案,尽管 Intellisense 错误很不幸。再次祝你好运!

关于typescript - Typescript 函数中的复杂签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48938826/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com