Typescript:有没有一种方法可以检查变量是否为具有嵌套属性的接口定义对象?

3

例如:

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

type TEST_TYPE = string|number;

interface TEST_INTERFACE {
    "test3" : boolean;
}

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

除了用户定义的类型保护之外,我不知道还有其他选项,因为没有办法在运行时检查接口。 - Josh Crozier
谢谢,我看了一下,似乎最适合用于单个顶层属性,对于多个嵌套属性来说会有些混乱。 - icda
1
如果对象不是通过构造器创建的,那么检查的唯一方法是 if (variable.test1 !== undefined && variable.test2 !== undefined)。如果是通过构造器创建的,那么可以使用 instanceof 进行检查:if (variable instanceof TEST_OBJECT) - Misaz
1个回答

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所说,用户定义类型守卫可能是正确的选择。可以通过与构建接口和类型相同的方式来构建这些内容:
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));
}

希望这有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接