Как указать, что свойство класса является целым числом?


я экспериментирую с TypeScript, и в процессе создания класса С полем "ID", которое должно быть целым числом, я немного запутался.

во-первых, в Visual Studio 2012 с плагином TypeScript я вижу "int" в списке типов intelliSense. Но я получаю ошибку компиляции, которая говорит: "имя' int 'не существует в текущей области".

Я просмотрел спецификации языка и вижу только следующие примитивные типы: number, string, boolean, null и неопределено. Нет целочисленного типа.

Итак, у меня осталось два вопроса:

  1. Как я должен указать пользователи моего класса что конкретное поле-это не просто "число", а целое число (и никогда не плавающая точка или десятичное число)?

  2. Почему я вижу "int" в списке intellisense, если это не допустимый тип?

обновление: все ответы, которые я получил до сих пор о том, как JavaScript не имеет типа int, было бы трудно применить тип int во время выполнения... Я все это знаю. Я спрашиваю, есть ли способ TypeScript для предоставления аннотации пользователям моего класса, что это поле должно быть целым числом. Может быть, комментарий какого-то конкретного формата?

7 67

7 ответов:

  1. Я думаю, что нет прямого способа указать, является ли число целым числом или с плавающей запятой. В разделе 3.2.1 спецификации машинописного текста мы видим:

    "...Тип примитива Number соответствует аналогично названному типу примитива JavaScript и представляет собой 64-разрядный формат двойной точности IEEE 754 с плавающей запятой..."

  2. Я думаю int Это ошибка в Visual Studio intelliSense. Правильно это number.

TypeScript-это надмножество JavaScript, которое не имеет понятия int. Он имеет только понятие числа, которое имеет плавающую точку.

С философской точки зрения, объем работы, который компилятор должен был бы выполнить для принудительного применения только целых чисел для типа TypeScript int, потенциально может быть массивным, и в некоторых случаях все равно невозможно будет гарантировать во время компиляции, что будут назначены только целые числа, поэтому невозможно надежно добавить int на TypeScript.

примеры

var myInt: number;
var myString: string;

myInt. // toExponential, toFixed, toPrecision, toString
myString. // charAt, charCodeAt, concat, indexOf, lastIndexOf, length and many more...

Ну, как вы видели, typescript не имеет плавающего типа данных, такого как язык javascript. Только есть number, которые охватывают все int и double в то же время; может быть, вы должны сделать функцию, которая принимает число и проверить его, если это int или double, возвращая некоторое состояние в случае ошибки / успеха. Что-то вроде этого как метод вашего класса:

function SetN(x:number) {
   var is_int = parseInt(x) === parseFloat(x);
   if(is_int) this.n = x;
   return is_int;
}

//..
y = 10.5;
if(SetN(y)) {
  //OK
} else {
   //error not set y isn't a int
}

Примечание: это doest не работает для 10.0 например, если вы действительно не хотите этого, возможно, вы должны передать его в строку и попробовать чтобы найти ..

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

int было зарезервировано для будущего использования ключевое слово в более ранние версии javascript (ECMAScript, если вы предпочитаете). Но это действительное слово сейчас (где "сейчас" приравнивается к "в последней спецификации").

например, в 262 году он все еще был зарезервирован,http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

Это было бы хорошим дополнением к TypeScript, чтобы иметь int тип данных реализован, но со всей проверкой типа во время компиляции и правила литья доступны.

в TypeScript вы можете приблизиться к тому, что иногда называют непрозрачным типом, используя маркер.

// Helper for generating Opaque types.
type Opaque<T, K> = T & { __opaque__: K };

// 2 opaque types created with the helper
type Int = Opaque<number, 'Int'>;
type ID = Opaque<number, 'ID'>;

// using our types to differentiate our properties even at runtime
// they are still just numbers
class Foo {
    someId: ID;
    someInt: Int;
}

let foo = new Foo();

// compiler won't let you do this due to or markers
foo.someId = 2;
foo.someInt = 1;

// when assigning, you have to cast to the specific type
// NOTE: This is not completely type safe as you can trick the compiler 
// with something like foo.someId = 1.45 as ID and it won't complain.
foo.someId = 2 as ID;
foo.someInt = 1 as Int;

// you can still consume as numbers
let sum: number = foo.someId + foo.someInt;

Это позволяет вам быть более явным в вашем коде относительно того, какие типы ожидают ваши свойства, и компилятор не позволит вам назначить примитивное значение без приведения. Это не производит никаких дополнительных .вывод js, и вы все еще можете использовать и использовать значения как любые типы, на которых они основаны. В этом примере я использую числа, но вы можете использовать строки и и другие типы тоже.

вы все еще можете обмануть компилятор, приняв что-то, что не является Int или Id в этом примере, но оно должно выскочить, если вы пытаетесь назначить 1.45 как Int или что-то в этом роде. У вас также есть возможность создавать вспомогательные функции, которые вы используете для создания своих значений для обеспечения проверки во время выполнения.

существует несколько различных способов создания "отмеченных" типов. Вот хорошая статья: https://michalzalecki.com/nominal-typing-in-typescript/

нет integer или float но number введите TypeScript, как в JavaScript. Но если вы хотите сказать программисту, что вы ожидаете integer тип вы можете попробовать использовать Псевдонимы Типа как

type integer = number;
type float = number;

// example:
function setInt(id: integer) {}

но это все равно number введите и вы можете получить float.

часть описания из документации:
"псевдонимы на самом деле не создают новый тип - он создает новое имя для ссылки на этот тип. Сглаживание примитива не является ужасно полезно, хотя его можно использовать в качестве формы документации."