Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 带有泛型参数的类的类型_Typescript_Generics - Fatal编程技术网

Typescript 带有泛型参数的类的类型

Typescript 带有泛型参数的类的类型,typescript,generics,Typescript,Generics,我正在设计一个小的API。在它中,开发人员定义了一个类和一个配置文件,允许他们在我的系统中使用它 以下是我的代码的简化: abstract class Box<T> { constructor(protected initialValue: T) {} public abstract getDefaultThing(): T; } type BoxType = typeof Box; interface Config { boxType: BoxType

我正在设计一个小的API。在它中,开发人员定义了一个类和一个配置文件,允许他们在我的系统中使用它

以下是我的代码的简化:

abstract class Box<T> {
    constructor(protected initialValue: T) {}

    public abstract getDefaultThing(): T;
}

type BoxType = typeof Box;

interface Config {
    boxType: BoxType;
    initialValue: any;
}

function loadConfig(config: Config) {
    // Need to "as any" this so TSC doesn't complain about abstract class
    return new (config.boxType as any)(config.initialValue);
}
这已经不起作用了-
config
中的
boxType
出现错误,因为
MyBox
Box
窄。很好,我真正想做的是重新定义我的
Config
接口,以键入check
initialValue
BoxType

type BoxType<T> = typeof Box<T>;

interface Config<T> {
    boxType: BoxType<T>;
    initialValue: T;
}
type-BoxType=框的类型;
接口配置{
箱型:箱型;
初始值:T;
}

这不管用。。。根本<代码>框已经是一个类型,并且在未实例化的情况下无法接受泛型。我知道在某种程度上我混合了价值观和类型,但是有没有办法让一个属性作为对一个可实例化泛型类的引用缩小到某个泛型类型?

如果您不使用
typeof Box
而是使用type
BoxType
作为构造函数签名,接受
t
并返回一个
Box


我的实际用例比我在那里得到的要复杂得多(
Box
实际上继承自
React.Component
,并且必须让状态和道具失效),这仍然非常有效。回答得好!
type BoxType<T> = typeof Box<T>;

interface Config<T> {
    boxType: BoxType<T>;
    initialValue: T;
}
abstract class Box<T> {
    constructor(public initialValue: T) {}

    public abstract getDefaultThing(): T;
}

type BoxType<T> = new (initialValue: T) => Box<T>;

interface Config<T> {
    boxType: BoxType<T>;
    initialValue: any;
}

function loadConfig<T>(config: Config<T>) {
    return new config.boxType(config.initialValue); // no cast 
}

class MyBox extends Box<string> {
  public getDefaultThing(): string { // there was a typo here this was any
      return `${this.initialValue} world`;
  }
}

const config = { // no explcit type needed
  boxType: MyBox,
  initialValue: "hello",
};

const loaded = loadConfig(config); // loaded is Box<string>

console.log(loaded.getDefaultThing()); // prints "hello world"
abstract class Box<T> {
    constructor(public initialValue: T) {}

    public abstract getDefaultThing(): T;
}

type BoxType<T, TBox extends Box<T>> = new (initialValue: T) => TBox;

interface Config<T, TBox extends Box<T>> {
    boxType: BoxType<T, TBox>;
    initialValue: any;
}

function loadConfig<T, TBox extends Box<T>>(config: Config<T, TBox>) {
    return new config.boxType(config.initialValue); // no cast 
}

class MyBox extends Box<string> {
  public getDefaultThing(): string { // there was a typo here this was any
      return `${this.initialValue} world`;
  }
}

const config = { // no explcit type needed
  boxType: MyBox,
  initialValue: "hello",
};

const loaded = loadConfig(config); // loaded is MyBox

console.log(loaded.getDefaultThing()); // prints "hello world"