打字稿:有没有办法检查变量是否是具有嵌套属性的接口定义对象?

时间:2017-01-29 03:00:28

标签: javascript typescript types typescript-typings typechecking

例如:

interface TEST_OBJECT {
    "test1" : TEST_TYPE;
    "test2" : TEST_INTERFACE
}

type TEST_TYPE = string|number;

interface TEST_INTERFACE {
    "test3" : boolean;
}

有没有办法检查变量是否是TEST_OBJECT?

1 个答案:

答案 0 :(得分:0)

如果您正在寻找TypeScript来自动为您提供运行时类型保护,那是不可能的。但实际上,编译器非常擅长缩小类型,具体取决于您对正在检查的对象的了解程度。例如,假设您知道的内容是TEST_OBJECTstring

function hasKey<K extends string>(k: K, x: any): x is Record<K, {}> {
  return k in x;
}

declare const obj: TEST_OBJECT | string;

if (hasKey("test2", obj)) {
  // it knows that obj is a TEST_OBJECT now
  console.log(obj.test1);
  console.log(obj.test2.test3 === false); 
} else {
  // it knows that obj is a string
  console.log(obj.charAt(0));
}

如果您不知道您正在检查的对象是什么,那么,正如@JoshCrozier所说,User-Defined Type Guards可能是要走的路。可以像构建接口和类型一样构建它们:

function hasKey<K extends string>(k: K, x: any): x is Record<K, {}> {
  return k in x;
}

function isTEST_INTERFACE(x: any): x is TEST_INTERFACE {
  return hasKey("test3",x) && (typeof x.test3 === 'boolean');
}

function isTEST_TYPE(x: any): x is TEST_TYPE {
  return (typeof x === 'string') || (typeof x === 'number');
}

function isTEST_OBJECT(x: any): x is TEST_OBJECT {
  return hasKey("test1", x) && isTEST_TYPE(x.test1) &&
    hasKey("test2", x) && isTEST_INTERFACE(x.test2);
}

// use it:
declare const obj: TEST_OBJECT | string
if (isTEST_OBJECT(obj)) {
  console.log(obj.test1);
  console.log(obj.test2.test3 === false); 
} else {
  console.log(obj.charAt(0));
}

希望有所帮助。