gpt4 book ai didi

typescript - 从传递函数的返回值推断函数泛型类型 U

转载 作者:行者123 更新时间:2023-12-03 16:46:43 25 4
gpt4 key购买 nike

在大多数情况下,具有泛型类型的函数可以从参数推断泛型类型。但是,如果参数是一个函数,其中泛型类型既是参数的一部分又是返回值的一部分,则有时不会推断出泛型类型。
带有用于存储项目的类的简化示例,其中项目的某些属性是自动生成的(例如自动生成 ID 的数据库):

/**
* Stores items of type T
*/
class Store<T> {

/**
* Return a function that creates items from supplied partial items merged with
* attributes U auto-generated by a generator function
*/
itemCreator<U>(
generate: (item: Omit<T, keyof U>) => U
): (item: Omit<T, keyof U>) => Omit<T, keyof U> & U {
return item => ({...item, ...generate(item)});
}
}

type Person = {
id: string;
name: string;
email: string;
age?: number;
};
所以,如果你创建一个 Store<Person>并提供一个发电机来自动生成 id ,返回的创建者函数只需要 nameemail .
但是,在某些情况下, U不推断:
作品:
const create = new Store<Person>()
.itemCreator(() => ({id: 'ID', extra: 42}));
// U is {id: string, extra: number}, `create` only needs to provide `name` and `email` :)
const person = create({name: 'John', email: 'john.doe@foo.com'}); // creates person with extra
不起作用:
const create = new Store<Person>()
.itemCreator(item => ({id: 'ID', extra: 42}));
// U is now unknown, meaning the `create` function must provide complete `Person` objects :(
const person = create({name: 'John', email: 'john.doe@foo.com'}); // does not compile
适用于显式 <U> :
const create = new Store<Person>()
.itemCreator<{id: string, extra: number}>((item) => ({id: 'ID', extra: 42}));
const person = create({name: 'John', email: 'john.doe@foo.com'}); // creates person with extra
现在,将部分项目传递给生成器的原因是一些自动生成的属性可能依赖于其他属性(例如 id 被生成为 email 属性的散列):
const creator = new Store<Person>()
.itemCreator(item => ({id: hash(item.email)}))
所以,我的问题是为什么推断 U如果 generate 的参数失败提供功能? TypeScript 是否简单地使用 U 的第一个找到的实例?或者是什么原因? generate函数返回 U ,所以如果它看到 {id: string}被退回,人们可能会争辩说 U也存在于 Omitgenerate 的参数类型应该无关紧要?
有没有办法解决这个问题?

最佳答案

@JHH,@Linda Paiste 您对下一个解决方案有何看法?:


class Store<T> {

itemCreator<U>(
generate: <P = Omit<T, keyof U>>(item: P) => U
): (item: Omit<T, keyof U>) => Omit<T, keyof U> & U {
return item => ({ ...item, ...generate(item) });
}
}

type Person = {
id: string;
name: string;
email: string;
age?: number;
};


const create = new Store<Person>()
.itemCreator(item => {
const x = item // Omit<Person, "id" | "extra">
return ({ id: 'ID', extra: 42 })
});
const person = create({ name: 'John', email: 'john.doe@foo.com' });


看起来 TS 很难推断 item参数,所以我用默认值定义了额外的泛型。
Here , 在我的博客中,您可以找到更多有趣的回调类型
Here您可以找到 Titian Cernicova Dragomir 对此行为的解释

If there is a parameter, the checker needs to decide U before checking the body, since there is no source for inference it goes with unknown. It then checks the body, but does not go back to try again with U = ret type it just checks the return compa. with U = unknown

关于typescript - 从传递函数的返回值推断函数泛型类型 U,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66706012/

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