关于typescript 使用类类型语法 new()?

在使用ts时,我看到有这样的语法,但是没明白这样定义的好处以及为什么这样定义?

function create<T>(c: {new(): T; }): T {
    return new c();
}

class BeeKeeper {
    hasMask: boolean;
}

class ZooKeeper {
    nametag: string;
}

class Animal {
    numLegs: number;
}

class Bee extends Animal {
    keeper: BeeKeeper;
}

class Lion extends Animal {
    keeper: ZooKeeper;
}

function createInstance<A extends Animal>(c: new () => A): A {
    return new c();
}

createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!
阅读 17.7k
3 个回答

看handbook也遇到同样的问题了,不了解ts的语法根本看不懂。
官网的handbook只有例子没有详细的定义,官网也没有spec的链接,差评。

TypeScript Language Specification
https://github.com/Microsoft/...


c:{new():T}里的'new'是Constructor Type Literal,下面new c()里的'new'是new operator,二者是不同的东西。

c:{new():T} 和 c:new()=>T是一样的,后者是前者的简写,意即C的类型是对象类型且这个对象包含返回类型是T的构造函数。

注意,':'后面是Type Information,这里的'=>'不是arrow function,只是用来标明函数返回类型。

3.8.9 Constructor Type Literals

A constructor type literal specifies the type parameters, regular parameters, and return type of a construct signature.

  ConstructorType:
   new TypeParametersopt ( ParameterListopt ) => Type

A constructor type literal is shorthand for an object type containing a single construct signature. Specifically, a constructor type literal of the form

new < T1, T2, ... > ( p1, p2, ... ) => R

is exactly equivalent to the object type literal

{ new < T1, T2, ... > ( p1, p2, ... ) : R }

Note that constructor types with multiple construct signatures cannot be written as constructor type literals but must instead be written as object type literals.

如果不使用 new(): T 你把这个功能写出来试试。

create 函数的参数是一个 Class,返回值是这个 Class 的实例。

c: T 的意思是,c 的类型是 T,但这个函数的目的不是要求 c 的类型是 T,而是要求 c 就是 T。

试比较一下:

let num = new Number(1);
fn(Number)
fn(num)

这里使用了泛型,能够让我们减少错误,写一个例子你就明白了:
`function showData(data){

return data;

}
showData('abc').length;
showData(12).length;//这样写js不报错但是是undefined
showData({ name: 'leo' }).length;
showData([12, 5, 8]).length;`
我们是很讨厌代码没有语法错误但是最终结果不对的,
用泛型就可以让编写阶段直接报语法错误,而不是语法正确,结果错误,代码如下:

function showData<T>(data:T){
    return data;
}
console.log(showData<string>('abc').length);
console.log(showData<number>(12).length);
console.log(showData({ name: 'leo' }).length);
console.log(showData([12, 5, 8]).length);

报语法错误,而不会被编译成js,这样就可以扼杀错误在摇篮之中

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Microsoft
子站问答
访问
宣传栏