Как использовать TypeScript, чтобы проверить, что объект не имеет перекрывающихся свойств с интерфейсом?

Как мне использовать TypeScript, чтобы проверить, что у объекта нет перекрывающихся свойств с интерфейсом?

Как только вы примете печальную истину о том, что вам потребуется поддерживать некоторый артефакт времени выполнения, связанный с V , поскольку сам V будет удален , и при условии, что вы на самом деле не можете использовать артефакт времени выполнения для определения V , лучшее, что вы можете сделать, это иметь компилятор кричит на вас, если ваш артефакт времени выполнения и V не синхронизированы. Вот один из способов сделать это:

 interface V { a: number; b: string; } const keysOfV = ["a", "b"] as const; type MutuallyAssignable{amp}lt;T extends U, U extends V, V = T{amp}gt; = void; // the following line will give an error if keysOfV is wrong type KeysOfVIsGood = MutuallyAssignable{amp}lt;keyof V, typeof keysOfV[number]{amp}gt;; // okay 

Обратите внимание на as const в определении keysOfV . Это const утверждение, и оно (или что-то в этом роде) необходимо для того, чтобы компилятор отслеживал буквальные строковые элементы keysOfV вместо того, чтобы keysOfV типа правильный, но слишком широкий string[] .

Тогда MutuallyAssignable{amp}lt;T, U{amp}gt; — это тип, который оценивается как void , но нам на самом деле не важно, к чему он относится. Нам важно то, что T ограничен U , а U ограничен T (через параметр по умолчанию, чтобы избежать нарушения кругового ограничения). Когда вы используете MutuallyAssignable{amp}lt;X, Y{amp}gt; для некоторых типов X и Y , вы получите ошибку компилятора, если компилятор не распознает, что X и Y взаимно назначаются.

Затем вы можете продолжить определять и использовать hasInvalidProperties() как хотите, используя keysOfV . Возможно, вот так:

 function hasInvalidProperties(x: object): x is { [K in keyof V]: Record{amp}lt;K, any{amp}gt; }[keyof V] { return Object.keys(x).some(k ={amp}gt; hasInvalidProperties.badKeySet.has(k)); } hasInvalidProperties.badKeySet = new Set(keysOfV) as Set{amp}lt;string{amp}gt;; /// test function getDataFromRequest(): object { return Math.random() {amp}lt; 0.5 ? { c: "okay" } : { a: "bad" }; } const x = getDataFromRequest(); if (hasInvalidProperties(x)) { console.log("not okay"); throw new Error(); } console.log("okay"); 

Главное событие — это то, что происходит, когда keysOfV не так. Вот что происходит, когда отсутствует запись:

 const keysOfV = ["a"] as const; type MutuallyAssignable{amp}lt;T extends U, U extends V, V = T{amp}gt; = void; // the following line will give an error if keysOfV is wrong type KeysOfVIsGood = MutuallyAssignable{amp}lt;keyof V, typeof keysOfV[number]{amp}gt;; // error! // "b" is not assignable to "a" ------{amp}gt; ~~~~~~~ 

И вот что происходит, когда у него есть дополнительная запись:

 const keysOfV = ["a", "b", "c"] as const; type MutuallyAssignable{amp}lt;T extends U, U extends V, V = T{amp}gt; = void; // the following line will give an error if keysOfV is wrong type KeysOfVIsGood = MutuallyAssignable{amp}lt;keyof V, typeof keysOfV[number]{amp}gt;; // error! // "c" is not assignable to "a" | "b" ---------{amp}gt; ~~~~~~~~~~~~~~~~~~~~~~ 

Надеемся, что эти сообщения об ошибках и их расположение достаточно наглядны, чтобы вы могли понять, как их исправить при изменении V


Хорошо, надеюсь, это поможет; удачи!

Ссылка на код

Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector