从传递函数的返回值推断函数泛型类型U
在大多数情况下,具有泛型类型的函数可以从参数推断泛型类型。但是,如果参数是一个函数,其中泛型类型既是参数的一部分又是返回值的一部分,则有时不会推断出泛型类型。
带有用于存储项目的类的简化示例,并且项目的某些属性是自动生成的(例如,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;
};
因此,如果您创建 aStore<Person>并提供一个生成器来自动生成id,则返回的创建者函数将只需要name和email。
但是,在某些情况下,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也存在于Omit该类型的参数来generate应该是无关的?
有没有办法解决这个问题?