Typescript Generics: возвращаемый тип вложенного экземпляра

#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, либо с помощью сужающих объявлений свойств.