почему тип параметра функции typescript выводится с ошибкой?

#typescript #typescript-typings #type-inference #typescript-generics

#typescript #typescript-typings #вывод типа #typescript-generics

Вопрос:

 class Base<T> {
    public state = {} as T;
    public getState(): T {
        return this.state
    }
    public setState(v: T) {
        this.state = v
    }
}

interface DogProps {
    name: 'hello';
    age: 123;
}

class Dog extends Base<DogProps> {
    public sayName() {
        console.log('name: ', this.state.name);
    }
    public sayAge() {
        console.log('age: ', this.state.age);
    }
}

function test<U, T extends Base<U>>(Cor: new () => T): [U, T] {
    const dog = new Cor();
    const state = dog.getState();
    return [state, dog];
}

const [state1, dog1] = test(Dog); // state1 is unknow

const [state2, dog2] = test<DogProps, Dog>(Dog); // verbose but right
  

демонстрационная игровая площадка

Я новичок в typescript.
Я думал, что код, который я написал, был правильным. Но это работает не так, как ожидалось.
Почему тип state1 неизвестен?
Могу ли я получить правильный тип без test<DogProps, Dog>(Dog) ?

большое спасибо!!!

Ответ №1:

Это побочный эффект того, как работает общее разрешение, typescript видит, что на это T ссылаются в аргументах, поэтому он пытается разрешить его, но ограничение основано на U , поэтому он пытается разрешить это в первую очередь. Поскольку U нигде не отображается в списке аргументов, он не может разрешить его, поэтому он заканчивается unknown

Если вы убедитесь, что это U присутствует в списке аргументов, вы можете гарантировать, что typescript сможет разрешить его, просто просмотрев входные данные без необходимости сначала выяснять T :

 function test<U, T extends Base<U>>(Cor: new()=>(T amp; Base<U>)): [U, T] {
                                                 // ^here^
}
  

Это должно устранить проблему 🙂

Комментарии:

1. Ты мой бог. Ты спас мне жизнь.

2. Я очень надеюсь, что ваша жизнь не зависит от чего-то подобного 🤣. Счастливого кодирования! 😁

3. Теперь я понял первый абзац, причину, по которой мой код не работает. Но я все еще не понимаю второй абзац, почему ваш код работает. Особенно without having to figure out T first . Поскольку возвращаемому параметру все еще нужен тип T. Не могли бы вы объяснить более подробно?

4. представьте, что вы являетесь typescript, вы смотрите на типы аргументов и пытаетесь выяснить, что U должно разрешаться. Но U нигде не указан только во входных аргументах T , так как вы можете выяснить, что U это такое? В какой-то момент typescript, вероятно, будет обновлен, чтобы справиться с этим случаем, но, по крайней мере, на сегодняшний день использование (T amp; (Constraint of T)) работает нормально.

5. Как человеческое существо, мы знаем, Dog extends Base тогда U's type должно быть DogProps . Но typescript кажется недостаточно умным. Кстати, не могли бы вы порекомендовать какие-либо книги, веб-сайт или статьи для изучения продвинутых навыков машинописи, например how generic resolution works . Кажется, что в документе typescript нет этих вещей.