typescript 如何定义具有已知和未知属性类型的对象[重复]

toiithl6  于 7个月前  发布在  TypeScript
关注(0)|答案(1)|浏览(81)

此问题在此处已有答案

How to define Typescript type as a dictionary of strings but with one numeric "id" property(3个答案)
7天前关闭。
我试图定义一个TypeScript类型,其中包含我知道的属性和我不知道的属性。它看起来像这样:

type MetaType = {
    res?: HttpResponse;
    req?: HttpRequest;
    [key: string]: string | number | boolean | string[]
}
// Error: Property 'res' of type 'HttpResponse' is not assignable to 'string' index type 'string | number | boolean | string[]'.ts(2411)

字符串
因此,如果它有一个属性res,它必须是一个HttpResponse,如果它有一个属性req,它必须是一个HttpRequest。其余的可以是任何字符串(除了resreq作为定义类型的键)。
我也试过这个:

type MetaType = {
    res?: HttpResponse;
    req?: HttpRequest;
} & Record<string, string | number | boolean | string[]>;
// No error


我没有得到任何类型的错误,但当我尝试使用它:

const meta: MetaType = {
    message: "hello",
    count: 12,
    req,
    res,
};
// Error: 
Type '{ message: string; count: number; req: HttpRequest; res: HttpResponse; }' is not assignable to type 'MetaType'.
  Type '{ message: string; cpi,t: number; req: HttpRequest; res: HttpResponse; }' is not assignable to type 'Record<string, string | number | boolean | string[]>'.
    Property 'req' is incompatible with index signature.
      Type 'HttpRequest' is not assignable to type 'string | number | boolean | string[]'.
        Type 'HttpRequest' is missing the following properties from type 'string[]': length, pop, push, concat, and 34 more


我也试过,但没有成功:

export type MetaType = {
    res?: HttpResponse;
    req?: HttpRequest;
    [key: Exclude<string, 'res' | 'req'>]: string | number | boolean | string[];
};
// Error: Property 'res' of type 'HttpResponse' is not assignable to 'string' index type 'string | number | boolean | string[]'.ts(2411)


这是我们可以用当前版本的TypeScript做的吗?有其他选择吗?

7xllpg7q

7xllpg7q1#

编辑:这里的问题似乎是,当使用索引类型时,附加到索引类型的值必须覆盖类型或接口声明中使用的所有类型。这意味着你可以做如下事情:

type MetaType = {
    res?: HttpResponse;
    req?: HttpRequest;
    [key: string]: string | number | boolean | string[] | HttpResponse | HttpRequest | undefined
}

字符串
请注意,您还必须添加undefined,因为您有可能未定义的可选字段。
当你要求一个替代方案,我会决定在设计水平的东西,除了试图代表所有可能的领域,你不知道。
为什么不使用Map作为附加属性,来存储所有既不是res也不是req的东西?例如:

type MetaType = {
    res?: HttpResponse;
    req?: HttpRequest;
    others: Map<string, any> = new Map<string, any>();
}

相关问题