空数组的打字稿初始化

时间:2020-05-18 16:18:49

标签: javascript typescript promise

我有一个像这样定义的promises数组。

export type PromisesArray = [
  Promise<IApplicant> | null,
  Promise<ICampaign | ICampaignLight> | null,
  Promise<IApplication[]> | null,
  Promise<IComment[]> | null,
  Promise<{ status: number; message: IActionTag[] }> | null,
  Promise<IHistoryEntry[]> | null,
  Promise<IDocs> | null,
  Promise<IForm> | null,
];

我想初始化为一个空值,例如const promisesArray = <PromisesArray>[]

但是,我遇到了以下错误:

Conversion of type '[]' to type 'PromisesArray' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type '[]' is missing the following properties from type '[Promise<IApplicant>, Promise<ICampaign | ICampaignLight>, Promise<IApplication[]>, ... 4 more ..., Promise<...>]': 0, 1, 2, 3, and 4 more.ts(2352)

然后我将数组中的某些项目推入,如下所示:

if (this._printOptions[EPrintOption.Tags]) {
  const applicantActionsTagsPromise = ApplicantService.getActions(this._applicantId);
  promisesArray.push(applicantActionsTagsPromise); // On this line
} else {
  promisesArray.push(null);
}

并遇到此错误。

Argument of type 'Promise<IActionTag[]>' is not assignable to parameter of type 'Promise<IApplicant> | Promise<ICampaign | ICampaignLight> | Promise<IApplication[]> | ... 4 more ... | Promise<...>'.
  Type 'Promise<IActionTag[]>' is not assignable to type 'Promise<IApplicant>'.
    Type 'IActionTag[]' is missing the following properties from type 'IApplicant': address, advertiseid, applicantid, birthdate, and 14 more.ts(2345)

我想在不使用any类型的情况下解决此问题。

3 个答案:

答案 0 :(得分:0)

这两种情况都可以解决您的问题。它必须非常复杂,因为您一次只将一个元素推入数组,而不是一次分配整个数组。如果要更改代码,以便同时分配整个Promise数组,则可以毫无问题地使用原始定义:

export type PromisesArray = []
  | [
    Promise<IApplicant> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null,
    Promise<IApplication[]> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null,
    Promise<IApplication[]> | null,
    Promise<IComment[]> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null,
    Promise<IApplication[]> | null,
    Promise<IComment[]> | null,
    Promise<{ status: number; message: IActionTag[] }> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null,
    Promise<IApplication[]> | null,
    Promise<IComment[]> | null,
    Promise<{ status: number; message: IActionTag[] }> | null,
    Promise<IHistoryEntry[]> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null,
    Promise<IApplication[]> | null,
    Promise<IComment[]> | null,
    Promise<{ status: number; message: IActionTag[] }> | null,
    Promise<IHistoryEntry[]> | null,
    Promise<IDocs> | null
  ]
  | [
    Promise<IApplicant> | null,
    Promise<ICampaign | ICampaignLight> | null,
    Promise<IApplication[]> | null,
    Promise<IComment[]> | null,
    Promise<{ status: number; message: IActionTag[] }> | null,
    Promise<IHistoryEntry[]> | null,
    Promise<IDocs> | null,
    Promise<IForm> | null
  ]
;

答案 1 :(得分:0)

我认为此解决方案有两个问题:

首先,您的类型定义了一个数组,该数组可以具有null个值,而不是undefined个值。

要使用正确的初始值,您应该使用:

const promisesArray = <PromisesArray>[null, null, null, null, null, null, null, null];

第二,Array.push不知道您当前所处的索引,因此将无法帮助您推断该特定数组元素的正确类型。

一种解决方案是立即声明整个数组as const。这将允许TypeScript将您的数组视为元组。每个元素都有自己的类型,而不是所有类型的并集。

enum Tags {
    String,
    Number,
    Boolean
}

type Options = {
    [key in Tags]?: boolean;
};

const options: Options = {
    [Tags.String]: true,
    [Tags.Boolean]: true
};

// Use `as const` to infer the type of the array as a tuple. 
const promiseArray1 = [
    options[Tags.Number] ? Promise.resolve(5) : null,
    options[Tags.Boolean] ? Promise.resolve(true) : null,
    options[Tags.String] ? Promise.resolve('string') : null
] as const;

// Alternatively declare the type as you did before.
type PromiseArray = [
    Promise<number> | null,
    Promise<boolean> | null,
    Promise<string> | null
];
const promiseArray2: PromiseArray = [
    options[Tags.Number] ? Promise.resolve(5) : null,
    options[Tags.Boolean] ? Promise.resolve(true) : null,
    options[Tags.String] ? Promise.resolve('string') : null
];

Playground

答案 2 :(得分:0)

如果最终定义的数组类型在每个位置都有如此特殊的类型。也许使用数组根本不是最好的选择。 如果您使用诸如

这样的命名属性来定义类型,那么您似乎会受益。
interface MyPromisesBundle {
  promiseIApplicant?: Promise<IApplicant>;
  promiseICampaign?: Promise<ICampaign>;
  ...
}
相关问题