Как ввести проверку псевдонима двоичного типа в Typescript - PullRequest
1 голос
/ 28 мая 2020

Я хотел бы, чтобы условие зависело от данного типа аргумента, но поскольку все возможные аргументы имеют один и тот же двоичный тип (число), я ищу способ создать какой-то псевдоним типа, который можно проверить для.

Это начальная идея, которая не работает, потому что машинописный текст скомпилирован в javascript и, таким образом, bonus всегда будет javascript типом number.

    type Percentage = number;

    class Foo {
      applyBonus(bonus: Percentage | number) {
        if (typeof bonus === 'Percentage') {
          console.log('Percent');
        } else {
          // it's always number, because at execution time we're in javascript land here
          console.log('number'); 
        } 
      }
    }

    let bar = new Foo();
    bar.applyBonus(5);
    bar.applyBonus(6 as Percentage);

Этот вопрос в основном сосредоточен на возможностях языка машинописного текста и на том, можно ли решить эту проблему с помощью функций машинописного текста. Было бы легко использовать объект вроде {value:6,type:'percent'} вместо числа двоичного типа.

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Типографский текст основан не на названиях вещей, а на их структуре. Вы можете назвать число как-нибудь иначе, но это все равно число. Percentage здесь просто псевдоним.

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

interface Percentage { percentage: number }

class Foo {
   applyBonus(bonus: Percentage | number) {
      if (typeof bonus === 'object') {
         console.log('Percent', bonus.percentage);
      } else {
         console.log('number', bonus); 
      } 
   }
}

new Foo().applyBonus(123)
new Foo().applyBonus({ percentage: 456 })

Игровая площадка


В качестве альтернативы (я не рекомендую это, но это интересно с академической точки зрения), вы можете создать подкласс Number и использовать его.

class Percentage extends Number { }

class Foo {
   applyBonus(bonus: Percentage | number) {
      if (bonus instanceof Percentage) {
         console.log('Percent', bonus);
      } else {
         console.log('number', bonus); 
      } 
   }
}

new Foo().applyBonus(123)
new Foo().applyBonus(new Percentage(456))

Но на самом деле, я бы поставил под сомнение вашу потребность в этом. Я не уверен, что вы пытаетесь сделать здесь sh, но, вероятно, есть более простой способ.

1 голос
/ 28 мая 2020

Пример кода

type Percentage = number;

    class Foo {
      applyBonus(bonus: Percentage | number) {
        if (typeof bonus === 'Percentage') {
          console.log('Percent');
        } else {
          // NO, IT IS NOT ALWAYS NUMBER BECAUSE OF THAT
          console.log('number'); 
        } 
      }
    }

    let bar = new Foo();
    bar.applyBonus(5);
    bar.applyBonus(6 as Percentage);

Реальная причина

JavaScript

JavaScript, а также любой другой язык программирования, поставляется с набором примитивных значений. Которые, поскольку es6 равны Шесть

  • число
  • строка
  • логическое
  • undefined
  • null
  • символ

Как вы могли заметить, Percentage не является одним из них.

то, что может быть правильным из вашего execution time we're in javascript land here утверждения, является фактом типы «не существуют на JS» ... не совсем верно, поскольку типы существуют в JS, но скомпилированный код из вашего примера выглядит примерно так

class Foo {
    applyBonus(bonus) {
      if (typeof bonus === 'Percentage') {
        console.log('Percent');
      } else {
        console.log('number'); 
      } 
    }
  }

  let bar = new Foo();
  bar.applyBonus(5);
  bar.applyBonus(6);

, если мы посмотрим на bar.applyBonus вы передаете 5 n 6 , которые являются двумя примитивными значениями, поскольку оба они являются числами

, если вы не верите, что я открываю консоль в браузере и вставьте это typeof 5

enter image description here

и «Процент»! == «число»

именно поэтому вы всегда попади внутрь остального. Единственный способ получить instanceof процент - это создать процент вызова объекта:

class Percentage {
  constructor (value) {
     this.value = value;
  }
}

 class Foo {
      applyBonus(bonus) {
        if (bonus instanceof === Percentage) {
          console.log('Percent');
        } else {
          // NO, IT IS NOT ALWAYS NUMBER BECAUSE OF THAT
          console.log('number'); 
        } 
      }
    }

    let bar = new Foo();
    bar.applyBonus(5);
    bar.applyBonus(new Percentage(6));
...