У меня есть объект, который может иметь n
количество свойств, каждое из которых одинаково, но с их n
значением в имени.
Пример:
const obj = {
'data-element-0': 'something',
'data-element-1': 'something else',
'data-element-2': 'something as well',
'data-element-3': 'something to feel included',
};
Есть ли способ определить этот интерфейс более конкретно, чем просто использовать
interface Obj {
[key: string]: string;
}
Если они должны быть последовательными без пробелов, существует ли разумный максимум n
или он потенциально неограничен?
Почему вы не используете string[]
?
Вы можете сделать что-то вроде этого:
type Key = `data-element-${1|2|3|4|5|6|7|8|9|0}`
const obj:Record<Key, string> = {
'data-element-0': 'something',
'data-element-1': 'something else',
'data-element-2': 'something as well',
'data-element-3': 'something to feel included',
'data-element-yu': 'something to feel included', // error
};
ОБНОВЛЯТЬ Я также сделал помощников для двойных чисел, от: 0-99:
type NonZeroDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type NumberHelper = {
[P in NonZeroDigit]: {
[Z in NonZeroDigit]: `${P}${Z}`
}
}
type NestedValues<T extends Record<string, Record<string, string>>> = {
[P in keyof T]: P extends string ? Values<T[P]> : never
}
type Values<T> = T[keyof T]
type RemoveTrailingZero<T extends string> = T extends `${infer Fst}${infer Snd}` ? Fst extends `0` ? `${Snd}` : `${Fst}${Snd}` : never;
type Numbers_99 = RemoveTrailingZero<Values<NestedValues<NumberHelper>>>
ОБНОВЛЯТЬ
Здесь у вас есть утилита для генерации диапазона чисел от 0 до 99999.
type Values<T> = T[keyof T]
type LiteralDigits = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
type NumberString<T extends number> = `${T}`
type AppendDigit<T extends number | string> = `${T}${LiteralDigits}`
type MakeSet<T extends number> = {
[P in T]: AppendDigit<P>
}
type RemoveTrailingZero<T extends string> = T extends `${infer Fst}${infer Rest}` ? Fst extends `0` ? RemoveTrailingZero<`${Rest}`> : `${Fst}${Rest}` : never;
type From_1_to_999 = RemoveTrailingZero<Values<{
[P in Values<MakeSet<LiteralDigits>>]: AppendDigit<P>
}>>
type By<V extends NumberString<number>> = RemoveTrailingZero<Values<{
[P in V]: AppendDigit<P>
}>>
type From_1_to_99999 =
| From_1_to_999
| By<From_1_to_999>
| By<From_1_to_999
| By<From_1_to_999>>
ОБНОВЛЕНИЕ 3
Если вы все еще хотите генерировать буквенные числа, а не строковые числа, вы можете использовать этот код, который был беззастенчиво украден из здесь
type PrependNextNum<A extends Array<unknown>> = A['length'] extends infer T ? ((t: T, ...a: A) => void) extends ((...x: infer X) => void) ? X : never : never;
type EnumerateInternal<A extends Array<unknown>, N extends number> = { 0: A, 1: EnumerateInternal<PrependNextNum<A>, N> }[N extends A['length'] ? 0 : 1];
type Enumerate<N extends number> = EnumerateInternal<[], N> extends (infer E)[] ? E : never;
type Result = Enumerate<43> // 0 | 1 | 2 | ... | 42
*ОБНОВЛЕНИЕ от 8 сентября 2021 г.
Начиная с TS 4.5, см. Хвостовая рекурсия PR, можно генерировать гораздо более длинный диапазон чисел.
См. пример:
type MAXIMUM_ALLOWED_BOUNDARY = 999
type ComputeRange<
N extends number,
Result extends Array<unknown> = [],
> =
(Result['length'] extends N
? Result
: ComputeRange<N, [...Result, Result['length']]>
)
const ComputeRange = (N: number, Result: number[] = []): number[] => {
if (Result.length === N) {
return Result
}
return ComputeRange(N, [...Result, Result.length])
}
// 0 , 1, 2 ... 998
type NumberRange = ComputeRange<MAXIMUM_ALLOWED_BOUNDARY>[number]
Я пытаюсь понять, как сделать это для двойного числа, например: 10|11|12|13 ....
Вы можете сделать это как это, но я не уверен, соответствует ли это варианту использования или нет. Если OP заботится о пробелах или хочет иметь неограниченный максимальный размер, тогда он становится более волосатым.
Также есть data-element-${number}
, но он принимает нецелые числовые значения. Положительным моментом является отсутствие встроенного максимального значения или огромного типа объединения.
Каковы ваши ограничения? Должны ли индексы начинаться с
0
? Должны ли они быть целыми числами? Должны ли они быть последовательными целыми числами без пробелов? и т.д.