首页 > 解决方案 > 如何定义与 JSON 兼容的参数以避免错误“索引签名丢失”?

问题描述

我有一个函数定义为:

export function useSubmitHandler(url: string, data: Json): [FormEventHandler<HTMLFormElement>, boolean] {}

在哪里Json

type JsonPrimitive = string | number | boolean | null | undefined
interface JsonMap extends Record<string, JsonPrimitive | JsonArray | JsonMap> {}
interface JsonArray extends Array<JsonPrimitive | JsonArray | JsonMap> {}
export type Json = JsonPrimitive | JsonMap | JsonArray

但是,如果我尝试使用任意接口调用它,则会出现错误:

TS2345: Argument of type 'Fee' is not assignable to parameter of type 'Json'.   
Type 'Fee' is not assignable to type 'JsonMap'.     
Index signature is missing in type 'Fee'

在此处输入图像描述

但是,如果我用同一个对象调用它但像这样传播,{...store.data}那么错误就会消失。

如何useSubmitHandler正确键入以便它接受任何 JSON 可字符串化的对象?

我认为Json类型是正确的,但它需要更多的东西来允许将任意类型传递给函数。


Fee是:

interface Fee {
    id: number|null;
    name: string;
    type: string;
    amount: string;
    default: number;
    company_id: number;
    deleted_at?: any;
    active: number;
    fee_or_discount: string;
}

当然,我希望它适用于任何类型。

标签: jsontypescript

解决方案


选项 1:重新定义Json类型

type JsonPrimitive = string | number | boolean | null;
type JsonMap = {
    [key: string]: JsonPrimitive | JsonMap | JsonArray;
}
type JsonArray = Array<JsonPrimitive | JsonMap | JsonArray>;
type Json = JsonPrimitive | JsonMap | JsonArray;

Fee选项 2:向接口添加索引签名

interface Fee {
    [property: string]: any;
    id: number|null;
    name: string;
    type: string;
    amount: string;
    default: number;
    company_id: number;
    deleted_at?: any;
    active: number;
    fee_or_discount: string;
}

选项 3:为索引签名添加内联类型断言,例如:

useSubmitHandler(Router.route('fees.store')!, store.data as {[property: string]: any})

也可以看看

TypeScript GitHub 问题请提供json基本类型 #1897


推荐阅读