TypeScript版本: 2.3.2
码
// example.js
var Person = function (firstNameOrPojo, lastName) {
if (typeof firstNameOrPojo === "string") {
this.firstName = firstNameOrPojo;
this.lastName = lastName;
} else {
return new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName);
}
};
Person.prototype.greet = function greet() {
return `Hello, I am ${this.firstName} ${this.lastName}.`;
};
var fred = new Person({firstName: "Fred", lastName: "Flintstone"});
console.log(fred.greet());
预期行为:
我希望tsc
可以编译此代码而没有错误或警告,尤其是考虑到返回的类型始终与期望的类型匹配时。
在JavaScript中,构造函数可以返回一个对象。 完成此操作后,返回的对象将成为整个new
表达式的结果(有关新操作符,请参见此
关于类型,我可以理解为什么TypeScript编译器会犹豫是否支持JavaScript语言的这种怪癖。 毕竟,编译器必须验证显式返回的值是否与返回undefined
的构造方法返回的类型相同(通常情况)。 我认为这应该得到支持,因为:
这是一种有用且流行的JavaScript技术
上面的代码在Node.js和浏览器中运行良好:
$ node example.js
Hello, I am Fred Flintstone.
实际行为:
tsc
在检查以下代码时发出错误:
$ tsc --allowJs --checkJs --outDir ./dist example.js
example.js(8,16): error TS2350: Only a void function can be called with the 'new' keyword.
实际上,无论返回什么,都可以正确找出类型。 当作为函数调用时,编译器知道使用返回类型,而当用作构造函数时,则知道实例类型。 该错误是.js文件需要解决的问题。 .ts文件仍然不允许使用该模式(因为我们在保守的一面出错)。
+1
尤其是现在有了Proxy
,可以通过直接返回代理而不是直接返回类实例来实现一些不错的行为。 除非我们可以推断或指定构造函数的返回类型,否则这是不可能的。
如果你能放get(target, name) {}
和set(target, name, value) {}
在类构造函数内部,以覆盖对象/数组(所有属性)的属性赋值运算符,那么... javascript不会很短。
[否则,返回带有处理程序功能的新代理就足够了。]
最有用的评论
+1
尤其是现在有了
Proxy
,可以通过直接返回代理而不是直接返回类实例来实现一些不错的行为。 除非我们可以推断或指定构造函数的返回类型,否则这是不可能的。