Запретить компиляцию, если не существуют все поля - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть этот машинописный код:

interface Foo {
  foo1: string,
  foo2: number,
  foo3: boolean
}


const v = <Foo>{foo1: '4'};

это компилируется - как я могу предотвратить его компиляцию, если в объекте не присутствуют все 3 поля?Прямо сейчас присутствует только одно из полей.

Вот мой вариант использования / обоснование: https://gist.github.com/ORESoftware/8d02fb30c53c19f6b38bddbc96da2475

Но если вы сделаете это так:

const v : Foo = {foo1: '4'};

тогда это не скомпилируется.И если вы сделаете это так:

  const v = <Foo>{x: '4'};

, это не скомпилируется.

1 Ответ

0 голосов
/ 16 ноября 2018

Он скомпилируется, потому что вы делаете утверждение.Вы в основном говорите: «Поверьте мне, компилятор TypeScript, это правильный тип».Это вообще обходит проверку.

Если ваш объект удовлетворяет типу, вам не нужно делать утверждение .Интерфейсы в TypeScript работают, фактически проверяя, что объект удовлетворяет интерфейсу, а не то, что он явно расширяет / реализует интерфейс.

interface ResponseBody {
  foo1: number;
  foo2: string;
  foo3: boolean;
}

function doSomething(value: ResponseBody) {
    console.log("Ok");
}

И, таким образом:

// This will work
doSomething({ foo1: 0, foo2: "zero", foo3: false });

// This will not work
// Argument of type '{ foo1: number; foo2: string; }' is not assignable to parameter of type 'ResponseBody'.
// Property 'foo3' is missing in type '{ foo1: number; foo2: string; }'.
doSomething({ foo1: 0, foo2: "zero" });

// This will not work
// Type 'number' is not assignable to type 'string'.
doSomething({ foo1: 0, foo2: 1, foo3: false });

// This will work
const r1: ResponseBody = { foo1: 4, foo2: "four", foo3: true };

// This will not work
// Type 'string' is not assignable to type 'number'.
const r2: ResponseBody = { foo1: '4' };

// This will not work
// Type '{ foo1: number; }' is not assignable to type 'ResponseBody'.
// Property 'foo2' is missing in type '{ foo1: number; }'.
const r3: ResponseBody = { foo1: 4 };

Итак, основной ответ: удалить <Foo>.Вам это не нужно.

Теперь, если объект, который вы передаете doSomething, приходит откуда-то еще и имеет тип any, TypeScript не может выполнить проверку.Так что не получится.Это те случаи, когда вам нужно добавить утверждение, чтобы TypeScript знал, что вы знаете, что делаете.Но это потому, что объект (и его поля) неизвестны во время компиляции, и поэтому вообще не могут быть проверены TypeScript.

...