简体   繁体   English

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

[英]Typescript: Is there a way to check if a variable is an interface-defined object with nested properties?

For example: 例如:

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

type TEST_TYPE = string|number;

interface TEST_INTERFACE {
    "test3" : boolean;
}

Is there a way to check if a variable is a TEST_OBJECT? 有没有一种方法可以检查变量是否为TEST_OBJECT?

If you're looking for TypeScript to automatically provide runtime type guards for you, that's not possible. 如果您正在寻找TypeScript为您自动提供运行时类型保护,那是不可能的。 In practice though, the compiler is pretty good at narrowing types for you, depending on how much you know about the object you're inspecting. 但是实际上,编译器非常适合您缩小类型,具体取决于您对所检查对象的了解程度。 For example, say you have something you know is either a TEST_OBJECT or a string : 例如,假设您知道某个东西是TEST_OBJECT或一个string

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));
}

If you have no idea what the object you're inspecting might be, then, as @JoshCrozier said, User-Defined Type Guards are probably the way to go. 如果您不知道要检查的对象是什么,那么就像@JoshCrozier所说的那样, 用户定义的类型防护可能是解决方法。 It's possible to build these up the same way you've built up your interfaces and types: 可以按照建立接口和类型的相同方式来建立这些:

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));
}

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM