TypeScript:如何声明记录或记录数组的类型?
Posted
技术标签:
【中文标题】TypeScript:如何声明记录或记录数组的类型?【英文标题】:TypeScript: How to declare type for Record or Array of Records? 【发布时间】:2021-06-07 07:52:59 【问题描述】:假设有一个apiCall
函数返回一个promise,它解析为具有data
属性的对象,该属性可以是Record
或Record
s 的数组(如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;[]' 中的以下属性:length、pop、push、concat 和另外 26 个。
我认为这可能与被视为 Record
【问题讨论】:
【参考方案1】:这是因为:
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
编译器能够计算出函数的返回类型
【讨论】:
重载是这种特定情况的一种方法(其中返回类型的差异由布尔参数决定)但在一个非最小示例中(如 axios 调用的用例中所述)显式重载签名并不那么简单(因为response.data
的类型是由传递给axios 的method
和url
定义的)
尝试与 axios 分享示例。不知道你的例子没那么简单)
顺便说一句,您可以随时使用Array.isArray
。它就像 TS 中的 typeguard 以上是关于TypeScript:如何声明记录或记录数组的类型?的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript:如何在编译时声明固定大小的数组以进行类型检查