В чем разница между константными утверждениями TypeScript и объявлениями? - PullRequest
2 голосов
/ 19 марта 2019

Я только что прочитал о новой функции подтверждения const в TypeScript 3.4 RC, и я не вижу, как она отличается от использования const объявлений.

Я проверил это на примере из страница объявления , которая, очевидно, демонстрирует, как использование as const (утверждение const) предотвращает расширение литеральных типов (например, с "circle" до string).

// Example from official announcement
function getShapes() {
  let result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 },
  ] as const;

  return result;
}

for (const shape of getShapes()) {
  if (shape.kind === "circle") {
    console.log("Circle radius", shape.radius);
  } else {
    console.log("Square side length", shape.sideLength);
  }
}

// Output:
// Circle radius 100
// Square side length 50

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

// Altered getShapes function
function getShapes() {
  const result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 },
  ];

  return result;
}

Так в чем же разница? На странице объявления перечислены три причины для использования const утверждений:

• никакие литеральные типы в этом выражении не должны быть расширены (например, нет перехода от слова "привет")в строку)
• литералы объекта получают свойства только для чтения
• литералы массива становятся кортежами только для чтения

, но это не объясняет разницу между утверждениями и объявленияминт.

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

В этом примере используется console.log для проверки предполагаемых типов. console.log не заботится о типе аргумента, поэтому в обоих случаях ошибок нет.

Результат отличается, если для теста требуется более конкретный тип:

// Altered getShapes function
function getShapes() {
  const result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 },
  ];

  return result;
}

for (const shape of getShapes()) {
  if (shape.kind === "circle") {
    const radius: number = shape.radius;
  } else {
    const length: number = shape.sideLength;
  }
}

При включенном --strictNullChecks вы получите две ошибки:

t.ts:25:11 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
  Type 'undefined' is not assignable to type 'number'.

25     const radius: number = shape.radius;
             ~~~~~~

t.ts:29:11 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
  Type 'undefined' is not assignable to type 'number'.

29     const length: number = shape.sideLength;
             ~~~~~~

Как было объявлено для этой функции, ошибок нет, когда утверждение as const используется, чтобы компилятор выводил точный тип.

Для справки вот тип, выведенный для типа возврата getShapes() с объявлением const:

 ( { kind: string; radius: number; sideLength?: undefined; } 
  |{ kind: string; sideLength: number; radius?: undefined; } ) []

Как видите, kind расширен до string, а тип элемента массива представляет собой объединение с элементами, у которых объявлены все свойства, только некоторые из них являются необязательными в некоторых членах объединения - поэтому вы не получаете ошибок например, в журнале консоли, когда вы регистрируетесь, shape.radius - console.log с удовольствием зарегистрирует undefined, если член объединения имеет неправильный тип.

Вот тип, выведенный для возвращаемого типа getShapes() с as const утверждением:

readonly [
   { readonly kind: "circle"; readonly radius: 100; }, 
   { readonly kind: "square"; readonly sideLength: 50; }
]

Теперь это тип кортежа только для чтения, а не массив, и он имеет точные типы для каждого члена кортежа (и, как и ожидалось, kind является правильным литеральным типом).

1 голос
/ 19 марта 2019

A const объявление - это объявление переменной, которое нельзя изменить после объявления. Это функция Javascript, которую поддерживает Typescript.

const x ={ n: 10} ;
x.n = 11; //ok
x= { n:11}; // error 

const утверждение - это утверждение типа, которое оказывает влияние, которое вы описали на цель утверждения.

const x ={ n: 10} as const;
x. n = 11; // error n is readonly 
...