#typescript
#typescript
Вопрос:
Я пытаюсь присвоить правильную форму объекту, который служит в качестве начального значения метода reduce . Этот объект может иметь динамическое количество свойств, а именем ключа могут быть числа от 1 до 6, последнее определяется в типе DiceNumber
type DiceNumber = 1 | 2 | 3 | 4 | 5 | 6;
const dataset: DiceNumber[] = [];
function rollDice(): DiceNumber {
return Math.floor(Math.random() * 6 1) as DiceNumber;
}
function stats(data: DiceNumber[]) {
return data.reduce((a, c) => {
a[c] = (a[c] || 0) 1;
return a;
}, {} as any);
}
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
dataset.push(rollDice());
console.log(stats(dataset));
Не используя any, я получаю следующее сообщение
Элемент неявно имеет тип ‘any’, поскольку выражение типа ‘DiceNumber’ нельзя использовать для индексации типа ‘{}’. Свойство ‘1’ не существует для типа ‘{}’
При попытке определить интерфейс следующим образом
interface MyType {
[key: DiceNumber]: number;
}
Я получаю следующее сообщение
Тип параметра подписи индекса не может быть типом объединения. Вместо этого рассмотрите возможность использования сопоставленного типа объекта.
Ответ №1:
Тип, который вы ищете, действительно является отображенным типом. Я бы предложил:
{ [K in DiceNumber]?: number }
это означает, что для каждого ввода ключа K
DiceNumber
тип объекта имеет необязательное свойство type number
. Вы также можете использовать встроенные типы утилит и вызывать их Partial<Record<DiceNumber, number>>
.
Итак, ваша функция теперь:
function stats(data: DiceNumber[]) {
return data.reduce((a, c) => {
a[c] = (a[c] || 0) 1;
return a;
}, {} as { [K in DiceNumber]?: number });
}
И вы можете проверить, что stats()
сигнатура вызова
/* function stats(data: DiceNumber[]): {
1?: number | undefined;
2?: number | undefined;
3?: number | undefined;
4?: number | undefined;
5?: number | undefined;
6?: number | undefined;
} */
как и ожидалось.
Ответ №2:
Попробуйте это:
type Accumulator = {
[K in DiceNumber]?: number
}
function stats(data: DiceNumber[]) {
return data.reduce((a: Accumulator, c: DiceNumber) => {
a[c] = (a[c] || 0) 1;
return a;
}, {});
}