#typescript #types
#typescript #типы
Вопрос:
Я хочу создать массив, в котором будет указано, какие строки будут индексировать свойства внутри объекта и что свойства объекта содержат только функции.
Что я понимаю, так это то, что я могу создать тип объединения только из массива:
Мой рабочий случай — это действие редуктора (инструкция) в React reducer (но его можно использовать в другом месте):
const InstructionsArray = [
'HANDLE_BUTTON_CONVERT_INPUT',
'HANDLE_CHECKBOX_CONVERT_ON_INPUT',
'HANDLE_CHECKBOX_DISPLAY_TAGS',
'HANDLE_TEXTAREA_INPUT',
'HANDLE_RUNTIME'
] as const;
Затем у меня есть объект типа со свойством:
instruction: typeof InstructionsArray[number]
Конечно, обычный массив позволил бы нам использовать любую строку в качестве индексов, но поскольку мы привели его как const
, теперь он допускает только строки, которые мы указали в array .
Что я на самом деле хочу, так это иметь объект, который будет иметь некоторые имена свойств as string
, и все свойства будут иметь значение function
. Я хотел бы указать только эти имена свойств ( string
) , но поскольку каждое значение будет a function
, я бы не хотел указывать его более одного раза, чтобы его можно было принять как должное.
Текущий код выглядит так:
const changersLabels = [
'inventory',
'quest'
] as const;
Но «тот же» способ не работает с подобным объектом:
keyboardRouter(changers: {[key:typeof changersLabels[number]:Function]}) {
//some stuff
}
Что я делаю не так и возможно ли это вообще?
Ответ №1:
Похоже, вам просто нужен сопоставленный тип, в котором есть ключи typeof changersLabels[number]
и все свойства Function
:
function keyboardRouter(changers: { [K in typeof changersLabels[number]]: Function }) {
changers.inventory // Function
changers.quest // Function
}
Сопоставленный тип немного похож на тип с подписью индекса, но это работает только там, где индекс имеет тип string
или тип number
. Для других типов, таких как объединение строковых литералов, вам нужен сопоставленный тип с in
оператором.
Который можно было бы слегка переработать, чтобы присвоить имя вашим ключам и использовать встроенный Record
тип утилиты:
type ChangersLabels = typeof changersLabels[number];
function keyboardRouter2(changers: Record<ChangersLabels, Function>) {
changers.inventory // Function
changers.quest // Function
}