function getModelDetails<T>(model: Partial<Record<keyof T, unknown>>): Record<keyof typeof model, unknown> {
return (model as unknown) as Record<keyof typeof model, unknown>;
}
interface Person {
firstName: string;
lastName: string;
age: number;
}
// person is assigned with an object with all the Person properties instead of only "firstName" and "lastName"
const person = getModelDetails<Person>({ firstName: 'jon', lastName: 'smith' });
无论如何都要返回传递给泛型函数的任何东西的类型,而不是仅仅返回类型的所有属性?
我也不想指定要返回的属性,我基本上想找到一种方法,根据传递给函数的属性来设置返回类型。
我什至不确定这是否可能,但在此先感谢;)
需要
// person only with {firstName:"...", lastName: "..."}
const person = getModelDetails<Person>({ firstName: 'jon', lastName: 'smith' });
答案 0 :(得分:2)
这里涉及两个通用值:模型的类型和我们传递的属性子集。您已经说过要指定第一个泛型,但允许推断第二个。这不是您可以使用单个功能完成的事情。您需要使用柯里化,也就是“双重功能”。
function getModelDetails<Model>() {
return function <Keys extends keyof Model>(model: Pick<Model, Keys>): Pick<Model, Keys> {
return model;
}
}
您可以使用返回类型 [K in Keys]: Model[K]
而不是 Pick<Model, Keys>
。它们的意思是一样的,但如果你手动写出来,那么当你将鼠标悬停在变量上时,你会得到 { firstName: string; lastName: string; }
而不是 Pick<Person, "firstName" | "lastName">
。看你喜欢哪个。
要使用此函数,您需要一组额外的括号 ()
来调用第一个将 Model
设置为 Person
的函数。
// person has type: Pick<Person, "firstName" | "lastName">
const person = getModelDetails<Person>()({ firstName: 'jon', lastName: 'smith' });
// error if adding unsupported property
// TS2345: Object literal may only specify known properties, and 'somethingElse' does not exist in type 'Pick<Person, keyof Person>'
const person2 = getModelDetails<Person>()({firstName: 'jon', lastName: 'smith', somethingElse: '' });
// if you don't set the first generic then you get type Pick<unknown, never> because we don't have any default value
const person3 = getModelDetails()({ firstName: 'jon', lastName: 'smith' });