【问题标题】:TypeScript - defintion/interface for object that is not an arrayTypeScript - 非数组对象的定义/接口
【发布时间】:2018-07-09 05:39:47
【问题描述】:

我在纠结 JS/JSON.stringify 的这个特性:

const v = [];
v.foo = 5;
v.start = true;
console.log(JSON.stringify({value: v}));

你会在控制台中得到这个:

{"value":[]}

所以我想创建的类型是一个对象而不是一个数组:

export const acceptsObjectsButNotArrays = function(v: MyType){
  v[marker] = true;
  console.log(JSON.stringify({value:v});
}

使用 TS,是否有我可以用于 MyType 的定义,可以确保它是对象而不是数组?

export interface ObjectButNotArray extends Object {
  [key:string]: any
}

它需要有一个索引签名,就像上面一样,所以我可以给它添加任意属性。

我能想到的最接近的事情是:

export type ObjectButNotArray = object & !Array<any>

虽然那个语法是假的。

【问题讨论】:

    标签: typescript typescript2.0 tsc


    【解决方案1】:

    数组是对象,所以基本上我们希望在需要基类型的情况下不允许派生类型,这在 OOP 术语中是不太好的。

    你不能直接定义这样的类型,但是你可以使用条件类型来确保你的函数不接受一个数组作为参数,如果传入一个数组则创建不兼容。如果参数是我们强加的数组对参数的额外限制,基本上使参数无法(或至少不可能)传入。

    export const acceptsObjectsButNotArrays = function <T extends { [n: string]: any }>(v: T & ErrorIfArray<T>) {
        v["marker"] = true;
        console.log(JSON.stringify({ value: v }));
    }
    
    type ErrorIfArray<T> = T extends any[] ? "Argument must be an array" : T;
    
    acceptsObjectsButNotArrays({ // ok
        a: ""
    });
    acceptsObjectsButNotArrays([]); // Type 'undefined[]' is not assignable to type '"Argument must be an array"'.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 2016-11-07
      • 1970-01-01
      • 2017-07-02
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 2016-05-16
      相关资源
      最近更新 更多