我为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>
尽管语法是伪造的。
答案 0 :(得分: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"'.