#typescript
Вопрос:
Итак, у меня есть система, в которой я использую атрибуты в виде символов.
const A = Symbol.for(":a")
const B = Symbol.for(":b")
const C = Symbol.for(":c")
interface Attributes {
[A]: string
[B]: number
[C]: boolean
}
const pattern_1 = [A, B]
const pattern_2 = [B, C]
Мне нужна функция, которая может определить тип объекта:
{ [A]: string, [B]: number }
Отpattern_1
[A, B]
{ [B]: number, [C]: boolean }
Отpattern_2
[B, C]
Я зашел так далеко
type AttributeKeys ReadonlyArray<keyof Attributes>
declare function pattern<Pattern extends AttributeKeys>(...attrs: Pattern): Pattern
const PATTERN = pattern(A, B) // inferred type is [typeof A, typeof B]
Чего я не могу сделать, так это изменить тип кортежа на объект. На следующем шаге я хочу, чтобы он сделал вывод, что я верну объект с ключами из массива в качестве ключей в новом типе объекта. Я хочу, чтобы тип ключей соответствовал тому, который объявлен в Атрибутах. Это самое большое расстояние, которое я смог пройти:
declare function pull1<T>(pattern: T): { [K in keyof T]: K extends keyof Attributes ? Attributes[K] : never }
const entity1 = pull1(PATTERN) // inferred type is [never, never]
declare function pull2<T>(pattern: T): { [K in keyof Attributes]: K extends T ? Attributes[K] : never }
const entity2 = pull2(PATTERN) // inferred type is { [A]: never, [B]: never, [C]: never }
Я не могу заставить это работать, нужна помощь! Вот ссылка на игровую площадку для машинописи, если кто-то думает, что сможет ее взломать.
пс. Я должен использовать символы, но все остальное-это просто то, что я пробовал. Если есть лучший способ, пожалуйста, поделитесь!
Комментарии:
1. Откуда функция получает значения свойств? Свойства объекта имеют не только типы, но и значения. Или вам просто нужен сопоставленный тип, а не функция?
2. Просто сопоставленный тип.
Ответ №1:
Вы можете просто использовать Pick
предопределенные сопоставленные типы:
declare function pull2<T extends Array<keyof Attributes>>(pattern: T): Pick<Attributes, T[number]>
const entity2 = pull2(PATTERN)
let a = entity2[A] // string
let b = entity2[B] // number
entity2[C] // err
Комментарии:
1. Отлично, спасибо!