Typescript 基于参数中泛型模型的返回类型 函数getModelDetails(模型:部分):记录{ 返回(模型未知)作为记录; } 接口人{ 名字:字符串; lastName:string; 年龄:人数; } //person被分配一个具有所有person属性的对象,而不仅仅是“firstName”和“lastName” const person=getModelDetails({firstName:'jon',lastName:'smith'});

Typescript 基于参数中泛型模型的返回类型 函数getModelDetails(模型:部分):记录{ 返回(模型未知)作为记录; } 接口人{ 名字:字符串; lastName:string; 年龄:人数; } //person被分配一个具有所有person属性的对象,而不仅仅是“firstName”和“lastName” const person=getModelDetails({firstName:'jon',lastName:'smith'});,typescript,typescript-typings,typescript-generics,Typescript,Typescript Typings,Typescript Generics,是否需要将传递给泛型函数的内容作为返回类型,而不只是返回所有类型的属性 我也不想指定要返回的属性,我基本上想找到一种方法,根据传递给函数的属性来获得返回类型 function getModelDetails<Model>() { return function <Keys extends keyof Model>(model: Pick<Model, Keys>): Pick<Model, Keys> { return mo

是否需要将传递给泛型函数的内容作为返回类型,而不只是返回所有类型的属性

我也不想指定要返回的属性,我基本上想找到一种方法,根据传递给函数的属性来获得返回类型

function getModelDetails<Model>() {
    return function <Keys extends keyof Model>(model: Pick<Model, Keys>): Pick<Model, Keys> {
        return model;
    }
}
我甚至不确定这是否可行,但请提前感谢;)

所需的

//仅具有{firstName:“…”,lastName:“…”}
const person=getModelDetails({firstName:'jon',lastName:'smith'});

这里涉及两个通用值:模型的类型和我们要传递的属性子集。您说过要指定第一个泛型,但允许推断第二个泛型。这不是用一个函数就能做到的。你需要使用咖喱,也就是“双重功能”


这里涉及两个通用值:模型的类型和我们要传递的属性子集。您说过要指定第一个泛型,但允许推断第二个泛型。这不是用一个函数就能做到的。你需要使用咖喱,也就是“双重功能”


你是说
函数getModelDetails(model:U):U
?谢谢你的评论。不幸的是,我不太想指定模型,但不想指定作为类型传递的模型属性,类似这样的
getModelDetails({firstName:“})
,它将在返回的类型中仅解析
{firstName:“…”}
。如果故意将结构类型强制转换为显式命名类型,则会丢失有关结构类型的所有信息,而将其转换为命名类型。一旦将类型
{firstName:string;lastName:string}
视为
{firstName?:string;lastName?:string;age?:number}
,则会丢失对象的确切和原始类型信息。如果没有上述类型信息,typescript无法知道实际存在哪些属性。您基本上概括了一个特定的类型,并明确地告诉typescript忘记所有的细节。@PedroFigueiredo这对TS来说几乎不是问题。这更像是一个逻辑谬误-您无法恢复丢失的信息,特别是当您明确地想丢失信息时。您唯一的选择是以某种方式捕获并保存该类型的信息,而不是完全删除它。闭合模式-可能有效,也可能无效。但是,由于您目前要求同时进行类型推断(针对特定类型信息)和类型转换(显式和手动)——两者都是同时进行的,相互冲突——这是不可能的。请注意,@lindapaste的回答已经展示了闭包模式。您可以根据自己的喜好对其进行调整,但这是一个很好的示例,可以用于整个“在删除之前捕获类型信息”模式。您的意思是
函数getModelDetails(model:U):U
?谢谢您的评论。不幸的是,我不太想指定模型,但不想指定作为类型传递的模型属性,类似这样的
getModelDetails({firstName:“})
,它将在返回的类型中仅解析
{firstName:“…”}
。如果故意将结构类型强制转换为显式命名类型,则会丢失有关结构类型的所有信息,而将其转换为命名类型。一旦将类型
{firstName:string;lastName:string}
视为
{firstName?:string;lastName?:string;age?:number}
,则会丢失对象的确切和原始类型信息。如果没有上述类型信息,typescript无法知道实际存在哪些属性。您基本上概括了一个特定的类型,并明确地告诉typescript忘记所有的细节。@PedroFigueiredo这对TS来说几乎不是问题。这更像是一个逻辑谬误-您无法恢复丢失的信息,特别是当您明确地想丢失信息时。您唯一的选择是以某种方式捕获并保存该类型的信息,而不是完全删除它。闭合模式-可能有效,也可能无效。但是,由于您目前要求同时进行类型推断(针对特定类型信息)和类型转换(显式和手动)——两者都是同时进行的,相互冲突——这是不可能的。请注意,@lindapaste的回答已经展示了闭包模式。您可以根据自己的喜好对其进行调整,但这是整个“在删除之前捕获类型信息”模式的一个很好的示例。非常感谢您的回答。不能给你“正确答案”,因为这不是我想要的(甚至不确定是否可能…)。因为对于功能的消费者来说,这不是一个很好的开发者体验。无论如何,完美的软件是不存在的,所以再次感谢大家!老实说,我倾向于使用第二种方法,似乎是一种更好的DX。非常感谢这个答案。不能给你“正确答案”,因为这不是我想要的(甚至不确定是否可能…)。因为对于功能的消费者来说,这不是一个很好的开发者体验。无论如何,完美的软件是不存在的,所以再次感谢大家!老实说,我倾向于使用第二种方法,这似乎是一种更好的DX
// 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' });