简体   繁体   English

使用 TypeScript 使函数的返回类型取决于其参数?

[英]Make return type of function depends on its arguments with TypeScript?

I have a function that returns a promise which can be either of 2 types:我有一个函数返回一个承诺,它可以是两种类型之一:

async profilesAll(
    ids: readonly number[],
    profileType: ProfileType.Staff | ProfileType.Pupil,
  ): Promise<(DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles)[]> {
   // lots of logic here
}

Elsewhere I'm calling this function.在其他地方我正在调用这个函数。 otherFunction 's return type is an array of DatabaseSchema.pupilProfiles otherFunction的返回类型是一个DatabaseSchema.pupilProfiles数组

const otherFunction = () => {
    const results = await ctx.models.room.profilesAll(
        [root.id],
        ProfileType.Pupil,
      );
    return results;
}

TypeScript throws an error as it believes the return type can be DatabaseSchema.staffProfiles or DatabaseSchema.pupilProfiles . TypeScript 会抛出错误,因为它认为返回类型可以是DatabaseSchema.staffProfilesDatabaseSchema.pupilProfiles However in reality the logic within profilesAll prevents this.然而实际上, profilesAll的逻辑阻止了这一点。

How can I remove this error?我怎样才能消除这个错误? Can I make profilesAll 's return type depend on the profileType argument?我可以让profilesAll的返回类型取决于profileType参数吗? I looked at conditional types but I can only see examples of them extending types, not using function arguments as I need.我查看了条件类型,但我只能看到它们扩展类型的示例,而不是根据需要使用函数参数。

You should use overloads:您应该使用重载:

async function profilesAll(ids: number[], profileType: ProfileType.Pupil): Promise<(DatabaseSchema.pupilProfiles)[]>
async function profilesAll(ids: number[], profileType: ProfileType.Staff): Promise<(DatabaseSchema.staffProfiles)[]>
async function profilesAll(
  ids: readonly number[],
  profileType: ProfileType.Staff | ProfileType.Pupil,
): Promise<DatabaseSchema.staffProfiles[]> | Promise<DatabaseSchema.pupilProfiles[]> {
   // lots of logic here
}

I don't think you can modify the return type based on the input parameter dynamically.我认为您不能根据输入参数动态修改返回类型。 However, in this specific case, you can specify the return type of your otherFunction by explicitly defining it.但是,在这种特定情况下,您可以通过显式定义来指定otherFunction的返回类型。

const otherFunction = (): DatabaseSchema.pupilProfiles => { ... }

This way your otherFunction return type is no longer DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles这样你的otherFunction返回类型不再是DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles but DatabaseSchema.pupilProfiles only. DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles但仅限DatabaseSchema.pupilProfiles

You can use function/method overloading for this declaration.您可以为此声明使用函数/方法重载。

Method方法

class Foo {
  //option 1:
  async profilesAll(ids: readonly number[], profileType: ProfileType.Staff): Promise<DatabaseSchema.staffProfiles[]>; 
  //option 2:
  async profilesAll(ids: readonly number[], profileType: ProfileType.Pupil): Promise<DatabaseSchema.pupilProfiles[]>; 
  //implementation:
  async profilesAll(ids: readonly number[], profileType: ProfileType.Staff | ProfileType.Pupil): Promise<(DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles)[]> {
      if (profileType === ProfileType.Staff) return getStaff(ids);
      
      return getPupils(ids);
  }
}

Note that you need the overloaded signatures first, then and the third implementation signature should be a merge of them.请注意,您首先需要重载签名,然后第三个实现签名应该是它们的合并。 See more on overloading here . 在此处查看有关重载的更多信息

This will then allow you to make type safe calls:这将允许您进行类型安全调用:

declare const instance: Foo;
//OK:
const pupils = await instance.profilesAll([1, 2, 3], ProfileType.Pupil);
//OK:
const staff  = await instance.profilesAll([1, 2, 3], ProfileType.Staff);
//Error - return type is not pupilProfiles:
const wrong: DatabaseSchema.pupilProfiles[]  = await instance.profilesAll([1, 2, 3], ProfileType.Staff);

Playground Link 游乐场链接

Function功能

Using functions and overloading them, is analogous but you wouldn't have a class in that case:使用函数并重载它们是类似的,但在这种情况下你不会有一个类:

//option 1:
async function profilesAll(ids: readonly number[], profileType: ProfileType.Staff): Promise<DatabaseSchema.staffProfiles[]>;
//option 2:
async function profilesAll(ids: readonly number[], profileType: ProfileType.Pupil): Promise<DatabaseSchema.pupilProfiles[]>;
//implementation:
async function profilesAll(ids: readonly number[], profileType: ProfileType.Staff | ProfileType.Pupil): Promise<(DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles)[]> {
    if (profileType === ProfileType.Staff) return getStaff(ids);
    
    return getPupils(ids);
}

/* ... */

//OK:
const pupils = await profilesAll([1, 2, 3], ProfileType.Pupil);
//OK:
const staff  = await profilesAll([1, 2, 3], ProfileType.Staff);
//Error - return type is not pupilProfiles:
const wrong: DatabaseSchema.pupilProfiles[]  = await profilesAll([1, 2, 3], ProfileType.Staff);

Playground Link 游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在TypeScript中,如何根据其参数之一的返回类型来确定函数的返回类型? - In TypeScript, how do I make a function's return type based on the return type of one of its arguments? 如何设置类型取决于 typescript 中的 function arguments? - How to set a type depends on function arguments in typescript? 返回类型取决于泛型的 Typescript 函数 - Typescript function whose return type depends on a generic 我如何让 typescript 根据 function2E977777777777777777777777777777777777777777777777777777777777777777777777777777777777BED18 的返回类型 functionC17A94F14Z 的返回类型来推断 function 的返回类型 - How do I get typescript to infer the return type of a function based on the return type on a function of its arguments 打字稿:取决于字符串参数值的函数返回类型 - Typescript: Function return type that depends on value of string parameter 打字稿:只键入函数的参数或返回类型 - Typescript: typing only the arguments or the return type of a function Typescript仅复制函数参数而不返回类型 - Typescript copying only function arguments and not return type Typescript 函数根据可选参数返回类型 - Typescript function return type based on optional arguments 如何基于参数中的函数返回类型指定打字稿条件类型 - How to specify typescript conditional type based on a function return type in the arguments Typescript function 返回类型取决于 arguments 的数量或类型 - Typescript function return type depending on number or type of arguments
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM