通过阅读本教程,我发现在Typescript中声明类的一种方法是像这样使用class
语法。
class Person {
constructor(name: string) {
this.name = name
}
}
编译后将生成以下Javascript代码。
//Generated by typescript 1.8.10
var Person = (function () {
function Person(name) {
this.name = name
}
return Person;
}());
我的问题是,是否可以像这样使用生成的Javascript语法在Typescript中声明一个类?
function Person(name: string) {
this.name = name
}
答案 0 :(得分:2)
根据microsoft/TypeScript#2310,这可能是种,但不建议使用。根据TS小组的说法,如果您使用的是TypeScript,则应直接使用class
。如果目标是ES2015或更高版本,则将按原样编译,如果目标是ES5,则将编译为您提到的功能。
如果要忽略该建议,则必须执行一些类型注释和断言才能获得所需的行为,并且最终将在编译输出中留下一些运行时无操作代码。而且它不是特别安全的类型(如果您在键入过程中犯了错误,编译器将不会抱怨)。
首先,您必须手动定义类实例的接口,因为编译器无法为您推断出它:
interface Person {
name: string;
}
然后,您必须给函数一个this
parameter,以便编译器理解在函数的实现内部,this
值应被视为类的实例。您还应该将函数从Person
重命名为其他名称(例如_Person
),因为在之后,您将无法将其类型更改为new
-。事实:
function _Person(this: Person, name: string) {
this.name = name;
}
最后,您可以将Person
定义为const
,其值与运行时重命名的函数相同,但在编译时给它一个构造函数签名:
const Person = _Person as any as new (name: string) => Person;
现在已设置为Person
是运行时的函数(即使您以ES2015 +为目标,也不是class
),但是编译器将其视为构造函数:
const p = new Person("Alice");
console.log(p.name); // Alice
所以,嗯,万岁?在任何生产环境中,像这样与编译器抗争并“取胜”可能都不值得。但是,我想看看如何做到这一点很有趣。
好的,希望能有所帮助;祝你好运!
答案 1 :(得分:1)
作为对已有答案的改进,您也可以采用以下方式:
python2
这样,即使您仍然在乎这些内容,也可以保留一些类型安全性。
通过这种方式,您还可以通过先将静态方法添加到interface Person {
name: string;
}
interface PersonConstructor {
new(name: string): Person;
}
const Person: PersonConstructor = function (this: Person, name: string) {
this.name = name;
} as any;
const p = new Person("Alice");
console.log(p.name); // Alice
来在Person
上定义静态方法。因此,您可以这样做:
PersonConstructor
然后再做:
interface PersonConstructor {
new(name: string): Person;
foo(bar: string): void;
}
并用Person.foo = (bar: string) => {
console.log(`foo ${bar}`);
}