Skip to content

Latest commit

 

History

History
38 lines (27 loc) · 2.3 KB

typeInstantiation.md

File metadata and controls

38 lines (27 loc) · 2.3 KB

Конкретизация типа для обобщений

Скажем, у вас есть что-то, например класс Foo, который имеет обобщённый параметр:

class Foo<T>{
	foo: T;
}

Вы хотите создать для него уточнённую версию для определенного типа. Паттерн состоит в том, чтобы скопировать элемент в новую переменную и дать ей описание типа с заменой обобщённых типов конкретными типами. Например, если вам нужен класс Foo<number>:

class Foo<T>{
	foo: T;
}
let FooNumber = Foo as { new ():Foo<number> }; // ссылка 1

В ссылке 1 вы говорите, что FooNumber это то же самое, что Foo, но просто относитесь к нему как к чему-то, что при вызове с оператором new дает экземпляр Foo<Number>.

Наследование

Паттерн утверждения типа небезопасен, поскольку он доверяет вам сделать всё правильно. Распространенный паттерн в других языках для классов - просто использовать наследование:

class FooNumber extends Foo<number>{}

Одно предостережение: если вы используете декораторы в базовом классе, то унаследованный класс может не иметь того же поведения, что и базовый класс (он больше не обёрнут декоратором).

Даже если вы не уточняете свои классы, вам все равно нужно придумать паттерн приведения / утверждения, который работает, для начала покажем общий шаблон утверждения, например:

function id<T>(x: T) { return x; }
const idNum = id as {(x:number):number};

Меня вдохновил этот вопрос на stackoverflow