Логическое значение как тип ключа объекта в TypeScript - PullRequest
1 голос
/ 17 марта 2020

Я хочу реализовать подобную переключателю функцию, аналогичную оператору when в Kotlin в Typescript.

Пример использования:

const a = 30;
const b = 10;

const result = when(
   {[a < b]: 'somethin'},
   {[a > b]: 'somethin else'},
   {[a >= b]: 'somethin else 2'},
)

>> result == 'something else'

Возвращает значение первый случай с условием, оцененным как true.

Я пытался сделать что-то вроде этого:

type Case<T> = { [key: boolean]: T };

function when<T>(...cases: Case<T>[]) {
  const index = cases.findIndex(c => c.hasOwnProperty(true));
  return index >= 0 ? cases[index][true] : undefined;
}

, но компилятор TS жалуется на An index signature parameter type must be either 'string' or 'number'.ts(1023).

Также, когда я пытаюсь сделать что-то вроде этого:

const foo = {[a > b]: 'something'};

TS снова выдает ошибку с A computed property name must be of type 'string', 'number', 'symbol', or 'any'.ts(2464)

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

Я не мог найти какой-либо способ сделать это в Интернете, поэтому я решил вместо этого:

function when<T>(...cases: [boolean, T][]) {
  const index = cases.findIndex(([condition, _]) => condition);
  return index >= 0 ? cases[index][1] : undefined;
}

when(
   {[a < b]: 'somethin'},
   {[a > b]: 'somethin else'},
   {[a >= b]: 'somethin else 2'},
)

Это нормально, но я нахожу синтаксис первого примера более приятен для просмотра.

Я что-то упустил или это ограничение текущей спецификации c?

1 Ответ

0 голосов
/ 18 марта 2020

TypeScript имеет строгую типизацию, такого принуждения ожидать не стоит. Ключи объекта в JavaScript должны быть строкой или числом. Вот почему TypeScript просит вас не использовать логические значения. Вы можете попробовать следующее решение:

type Case<T> = { [key in "true" | "false"]: T };

Однако вы должны знать, что у вас не может быть двух одинаковых ключей: см. Пример ниже:

let sampleObject = {
    "true": 'something',
    "false": 'something else',
    "false": 'something else 2'
}

console.log(sampleObject);
// will print { true: "something", false: "something else 2" }
// note that the second value is not available because
// you cannot have 2 "false" keys
```

...