Допустим, мне нужно создать объект на основе потенциальных значений типа. Как мне сузить этот объект?
type Values = {
foo: boolean,
bar: string
}
type Properties<Type> = {
name: keyof Type;
// I want to narrow values so that it only accepts the matching value from Type
values: Type[keyof Type][];
};
const properties: Properties<Values>[] = [
{
name: 'foo',
// Should complain because 'false' !== boolean
values: [true, 'false'],
},
{
name: 'bar',
// Should be ok
values: ['hello', 'goodbye'],
}
];
@Caleth К сожалению, я. Я пытаюсь ввести существующую систему, не переписывая много кода.
вы можете использовать сопоставленные типы для этого.
Проблема в том, что в настоящее время союз создается на основе возможного значения. Если вместо этого вы сопоставите ключи и создадите тип вывода, как вы хотите, вы получите тип объекта со всеми возможными типами.
Затем, если вы индексируете сопоставленный тип с помощью keyof Type
, вы можете получить правильно сопоставленные значения.
Такой тип может работать
type Properties<Type> = {
[K in keyof Type]: { name: K; values: Type[K][] };
}[keyof Type];
Более детально детская площадка
Форматирование носит субъективный характер, но, конечно же, никто не хочет смотреть на код с нулевым пробелом между символами, поэтому я пошел дальше и отформатировал код.
Фантастика, спасибо! Итак, в этом случае перед индексацией мы создаем что-то вроде: foo: { name: foo, values: boolean[] }, bar: { name: foo, values: boolean[] }
? Как работает индексация? Я изо всех сил пытаюсь понять, что немного.
да, хороший, создается именно этот тип, в основном он просто объясняет все возможные варианты по ключу. Но нам не нужны ключи, поэтому, если вы обращаетесь к объекту, говоря keyof, он в основном дает вам только значения. У вас может быть тип ValueOf<T>=T[keyof T] Предположим, у нас есть вышеупомянутый тип T. Если вы делаете T['foo'] просто получаете часть foo, поэтому вы делаете T['foo'|'bar' ] вы получаете объединение части foo и части bar, и в обобщенном виде оно становится keyof T и дает T[keyof T] = объединение всех значений
Итак, это: A) перебирает объединение? или B) создает объединение, а затем сопоставляет шаблоны TS на основе предоставленного имени?
На самом деле, я думаю, что последнее, как эта игровая площадка, кажется, иллюстрирует
Да, вот и все, я думаю, что нет такой вещи, как повторяющийся союз. Его 2 шага. Сначала создайте отображаемый тип. Затем получите доступ к нему с помощью keyof, я думаю, что тонкая часть, которую нужно понять, это то, что keyof создает союз. В этом примере keyof Values - "foo"|"bar". Я добавлю ссылку на игровую площадку машинописного текста с некоторыми деталями, которые должны быть немного более понятными.
Вы можете написать класс, который создается только путем кода, который проверяет тип
class Property<Type> {
private name_: keyof Type;
private values_: Type[keyof Type][]
private constructor(name: keyof Type, values: Type[keyof Type][])
{
this.name_ = name;
this.values_ = values;
}
get name(): keyof Type { return this.name_; }
get values(): Type[keyof Type][] { return this.values_; }
static make<Type, K extends keyof Type>(name: K, values: Type[K][]): Property<Type>{
return new Property<Type>(name, values);
}
};
Вы привязаны к
Properties<Type>
структуре{ name: string, values: something[] }
?