#typescript #typescript-typings #typescript-generics
#typescript #typescript-типизации #typescript-generics
Вопрос:
У меня есть структура данных, которая выглядит следующим образом:
interface A{
propertyA: SubProperty<string>;
propertyB: SubProperty<number>;
propertyD: number;
}
type supported = string | number;
class SubProperty<T extends supported>{
data:T
}
type PropertyOfValue<T, V> = {
[K in keyof T]-?: T[K] extends V
? K
: never
}[keyof T];
type B = PropertyOfValue<A, SubProperty<supported>>;
class ParentClass{
constructor(protected a:A, protected b:B){}
getSubPropertyType(){
// I would like that function to return the type of this.a[this.b].data
return typeof this.a[this.b].data;
}
}
const a:A = {
propertyA: new SubProperty<string>(),
propertyB: new SubProperty<number>(),
propertyD: 1
}
class ChildClass extends ParentClass{
constructor(){
super(a, 'propertyA');
console.log(this.getSubPropertyType())
}
}
var test = new ChildClass();
console.log(test.getSubPropertyType())
Как я могу указать компилятору typescript, что это test.getSubPropertyType()
может быть только строка или неопределенный?
Как я могу явно сообщить ему, что это не может быть другой тип?
Комментарии:
1. Я не уверен, что понимаю вопрос. Это то, что вы ищете? Если нет, не могли бы вы добавить текст или код, который точно описывает, что вы пытаетесь сделать? Может быть, показать какой-нибудь пример кода с ошибкой, в котором вы не ожидаете ошибки? Удачи!
2. Это было именно то, что я искал. Но есть ли способ иметь такое же поведение без изменения подписи родительского класса? Я имею в виду, не делая его универсальным? Я хотел бы изменить только
getSubPropertyType
функцию.3. @jcalz Есть 2 вещи, которые беспокоят меня в вашем решении. 1- Мне придется изменить все
ChildClass
обычаи. 2 — У меня нет интеллекта в общем типе дляclass ParentClass<BB extends B>
4. Вам придется изменить обычаи, да. Вы могли бы сделать это вместо этого, если хотите, используя полиморфный
this
вместо generics . Но тогда вам все равно придется изменять дочерние классы, чтобы явно сузить типb
, и, кромеb
того, он должен быть общедоступным. Мне интересно, как вы ожидаете, что компилятор узнает, чтоb
это уже, не сообщая об этом? Я рад написать ответ, но я все еще не уверен, соответствует ли он вашим потребностям, или у вас просто возникнут дополнительные проблемы.5.Это не работает таким образом; вы определили
ParentClass
так, чтобы егоb
свойством было объединение"propertyA" | "propertyB"
. То, что вы инициализируетеChildClass
b
свойство для"propertyA"
него, не означает, что компилятор считает, что оно всегда будет иметь это конкретное значение. Такие сужения, основанные на анализе потока управления, не сохраняются в границах функций. Компилятор видитb
как"propertyA" | "propertyB"
, если вы явно не сообщите ему, что он не изменится… либо с помощью generics, либо с помощью сужающих объявлений свойств.