繁体   English   中英

如何基于泛型类型的 object 属性参数返回类型

[英]How to return type based on the object properties parameter with generic type

如果用户将异步设置为 true,我想返回 promise。

似乎 typescript 将始终采用 Create 接口的类型。 我将如何创建一个用于定义返回类型的类型?

interface Create<T> {
  options: {
    async: boolean;
  };
  properties: T;
}

type Return<T extends Create<any>> = T["options"]["async"] extends true ? Promise<boolean> : boolean;

const create = <T>(value: Create<T>): Return<Create<T>> => {
  return true;
};

interface User {
  username: string;
  password: string;
}

// is not promise
create<User>({
  options: {
    async: true,
  },
  properties: {
    username: "",
    password: "",
  },
});

您只需要为async选项添加一个通用类型参数,以便您可以使用它来推断正确的返回类型:

TS游乐场

type Create<Properties, IsAsync extends boolean> = {
  options: { async: IsAsync };
  properties: Properties;
};

type CreateResult<IsAsync extends boolean> = IsAsync extends true ? Promise<boolean> : boolean;

declare function create <Properties, IsAsync extends boolean>(
  input: Create<Properties, IsAsync>,
): CreateResult<IsAsync>;

type User = {
  username: string;
  password: string;
};

declare const userProps: User;

// Using the literal `true` results in a Promise:
const r1 = create({ options: {async: true}, properties: userProps });
    //^? const r1: Promise<boolean>

// Using the literal `false` results in a boolean:
const r2 = create({ options: {async: false}, properties: userProps });
    //^? const r2: boolean

// Using an indeterminate boolean variable results in a union of either possibility:
declare let isAsync: boolean;
const r3 = create({ options: {async: isAsync}, properties: userProps });
    //^? const r3: boolean | Promise<boolean>


更新以回应您的评论

TS游乐场

declare function create <IsAsync extends boolean>(
  input: {
    options: { async: IsAsync };
    properties: unknown;
  },
): IsAsync extends true ? Promise<boolean> : boolean;

这是我能做的最好的。 我不喜欢在返回时使用类型断言,但我找不到解决方法。

interface Create<T> {
  options: {
    async: boolean;
  };
  properties: T;
}

type Return<T> = T extends { options: { async: true } } ? Promise<boolean> : boolean;

const create = <T extends Create<any>>(value: T): Return<T> => {
  if (value.options.async === true) {
    return new Promise<boolean>((resolve) => resolve(true)) as Return<T>;
  }
  return true as Return<T>;
};

interface User {
  username: string;
  password: string;
}

create<Create<User>>({
  options: {
    async: true,
  },
  properties: {
    username: '',
    password: '',
  },
});

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM