TypeScript:如何声明记录或记录数组的类型?

问题描述 投票:0回答:1

假设有一个

apiCall
函数返回一个 Promise,该 Promise 解析为具有
data
属性的对象,该属性可以是
Record
Record
数组(如 Axios)。 我试图适当地声明类型,但出现错误。

这是我声明类型的方式:

type ApiResponseType = {
    data: Record<string, any>[] | Record<string, any>;
};

function apiCall(asArr: boolean): Promise<ApiResponseType> {
    const d = {
        foo: 'bar',
    };
    return Promise.resolve({
        data: asArr ? [d] : d,
    });
}

但是当我像这样使用它时:

(async()=>{
    let a: {[key: string]: any} | null = null;
    let b: {[key: string]: any}[] | null = null;
    a = (await apiCall(false)).data;
    b = (await apiCall(true)).data; // Type 'Record<string, any> | Record<string, any>[]' is not assignable to type '{[key: string]: any;}[] | null'. Type 'Record<string, any>' is missing the following properties from type '{[key: string]: any;}[]': length, pop, push, concat, and 26 more.
    console.log({a, b});
})();

我收到以下错误:

输入“记录”| Record[]' 不可分配给类型 '{[key: string]: any;}[] |无效的'。类型“Record”缺少类型“{[key: string]: any;}[]”中的以下属性:长度、弹出、推送、连接以及其他 26 个属性。

我认为这可能与数组被视为记录有关

typescript
1个回答
0
投票
这是因为:

declare var a: Record<string, any>[] declare var b: Record<string, any> a = b // error b = a // ok
记录数组可分配给记录,但反之则不然。

但是让我们回到你的例子:

type Data = Record<string, any>[] | Record<string, any>; type Nullable<T> = T | null type ApiResponseType<T extends Data> = { data: T }; function apiCall(asArr: true): Promise<ApiResponseType<Record<string, any>[]>> function apiCall(asArr: false): Promise<ApiResponseType<Record<string, any>>> function apiCall(asArr: boolean) { const d = { foo: 'bar', }; return Promise.resolve<ApiResponseType<Data>>({ data: asArr ? [d] : d, }); } type O = ReturnType<typeof apiCall> (async () => { let a: Nullable<Record<string, any>> = null; let b: Nullable<Record<string, any>[]> = null; a = (await apiCall(false)).data; b = (await apiCall(true)).data; // without LET bindings { const a = (await apiCall(false)).data; // Record<string, any> const b = (await apiCall(true)).data; //Record<string, any>[] } })();
借助重载,我们可以给编译器一些提示。

请参阅此部分:

// without LET bindings


编译器能够计算出函数的 ReturnType

© www.soinside.com 2019 - 2024. All rights reserved.