TypeScript: используйте аргумент типа пространства имен в общем - PullRequest
0 голосов
/ 11 октября 2018

У меня есть универсальный метод

abstract run<T> (options: T): void;

И затем в реализации, скажем, я хочу, чтобы тип T был классом B, который находится в пространстве имен A. TSLint жалуется, если я использую

run <A.B> (options: A.B) : void 

Ошибка:

Type '<A, B>(options: B) => void' is not assignable to type '<T>(options: T) => void'

Кажется, что точка '.'читается как ','?Как мне передать тип?

1 Ответ

0 голосов
/ 11 октября 2018

Если метод является базовым в базовом классе, он не может быть реализован только для одного типа в производном классе.Это нарушит принципы ООП, поскольку вы не можете использовать производный класс там, где ожидается базовый класс:

namespace A {
    export class B { private x!: string}
}
abstract class Abs {
    abstract run<T>(p: T): void;
}
class Impl extends Abs{
    run(p: A.B) { } // We get an error here as we should but if this were allowed we would get the error below
}

let a: Abs = new Impl();
a.run(""); // Impl expects A.B, but Abs will let us pass in any T not ok

Примечание Синтаксис, который вы используете, также неверен, вы можете указать толькосогласованные типы в вызовах в качестве аргументов универсального типа, вы не можете использовать тип в качестве параметра типа в объявлении функции / метода.Для этого нет синтаксиса, потому что он, как правило, не имеет смысла, как описано выше.

Хорошим вариантом было бы вместо этого переместить параметр универсального типа в класс:

namespace A {
    export class B { private x!: string}
}
abstract class Abs<T> {
    abstract run(p: T): void;
}
class Impl extends Abs<A.B>{
    run(p: A.B) { } // ok now
}

let a: Abs<A.B> = new Impl();
a.run(new A.B()); // type safe
...