У меня есть тип объединения строк, например:
type Suit = 'hearts' | 'diamonds' | 'spades' | 'clubs';
Мне нужен безопасный тип, чтобы получить все возможные значения, которые можно использовать в этом объединении строк. Но поскольку интерфейсы в основном являются конструкцией-временем, я могу это сделать лучше всего:
export const ALL_SUITS = getAllStringUnionValues<Suit>({
hearts: 0,
diamonds: 0,
spades: 0,
clubs: 0
});
export function getAllStringUnionValues<TStringUnion extends string>(valuesAsKeys: { [K in TStringUnion]: 0 }): TStringUnion[] {
const result = Object.getOwnPropertyNames(valuesAsKeys);
return result as any;
}
Это работает нормально, функция гарантирует, что я всегда передаю объект, где каждый ключ является элементом объединения строк и что каждый элемент включен, и возвращает массив строк из всех элементов. Поэтому, если объединение строк всегда изменяется, вызов этой функции будет ошибкой во время компиляции, если он также не будет обновлен.
Однако проблема, сигнатура типа для константы ALL_SUITS
равна ('hearts' | 'diamonds' | 'spades' | 'clubs')[]
. Другими словами, TypeScript считает, что это массив, содержащий не более или менее этих значений, возможно, с дубликатами, а не массив, содержащий все значения только один раз, например. ['hearts', 'diamonds', 'spades', 'clubs']
.
Мне бы очень хотелось, чтобы моя универсальная функция getAllStringUnionValues
указывала, что она возвращает ['hearts', 'diamonds', 'spades', 'clubs']
.
Как я могу достичь этого в общем, будучи DRY насколько возможно?