2

Например:Typcript: Есть ли способ проверить, является ли переменная объектом, определенным интерфейсом, с вложенными свойствами?

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

type TEST_TYPE = string|number; 

interface TEST_INTERFACE { 
    "test3" : boolean; 
} 

Есть ли способ проверить, если переменная является TEST_OBJECT?

+0

Возможно, вы ищете [User-Defined Type Guards] (https://www.typescriptlang.org/docs/handbook/advanced-types.html), кроме этого, я не знаю никаких других опций так как нет возможности проверять интерфейс. –

+0

спасибо, я посмотрел на него, и кажется, что он лучше всего используется для одного свойства верхнего уровня и будет бесполезным для множества вложенных свойств – icda

+1

, если объект не создан конструктором, только один способ проверить: 'if (variable .test1! == undefined && variable.test2! == undefined) '. Если это вы можете chcek путем instanceof 'if (variable instanceof TEST_OBJECT)'. – Misaz

ответ

0

Если вы ищете TypeScript для автоматически, то для вас предусмотрены защитные функции времени выполнения, это невозможно. На практике, однако, компилятор довольно хорош для сужения типов для вас, в зависимости от того, насколько вы знаете об объекте, который вы проверяете. Например, у вас есть что-то вы знаете, является либо 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)); 
} 

Если вы не имеете ни малейшего представления о том, что объект вы инспектирование может быть, то, как сказал @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)); 
} 

Надеюсь, что это поможет.

Смежные вопросы