javascript – 从非类继承ES6 / TS类

栏目: JavaScript · 发布时间: 7年前

内容简介:http://stackoverflow.com/questions/34576731/inherit-es6-ts-class-from-non-class

给定类从非类扩展(包括但不限于函数),

function Fn() {} 

class Class extends Fn {
    constructor() {
        super();
    }
}

有什么后果?规格说的是什么?

看起来像现在的Babel,Google V8和Mozilla Spidermonkey的实现一样,TypeScript throws

Type ‘() => void’ is not a constructor function type

如果这是一个有效的ES2015代码,那么在TypeScript中处理它的正确方法是什么?

TypeScript Part

到目前为止, spec 表示,扩展角色必须跟随TypeReference.而一个 TypeReference 必须是A.B.C<TypeArgument>的形式,像MyModule.MyContainer<MyItem>.所以在语法上你的代码是正确的.但这不是打字的情况.

该规范说BaseClass必须是一个有效的typescript类.但是,规范已经过时了,如 here 所示.现在,只要将表达式计算为构造函数,TypeScript就可以在extends子句中使用表达式.这个定义是,基于实现.你可以看到它 here .简单来说,如果一个表达式实现了new(){}接口,那么一个表达式可以算作构造函数.

ES2015 Part

所以,你的问题是简单的函数在TypeScript中不被识别为构造函数,这是有争议的,因为ES2015规范只需要对象具有[[construct]]内部方法.虽然用户定义的函数对象确实有它.

ES2015 在运行时需要BaseClass is a constructor .一个对象isConstructor,如果它有[[construct]] internal methd .规范说[[construct]]是 Function Object 的内部方法.用户函数是Function Objects的实例,因此它们是构造函数.但 builtin functionarrow function 可以没有[[构造]].

例如,以下代码将抛出运行时TypeError,因为parseInt是一个内置函数,没有[[construct]]

new parseInt()
// TypeError: parseInt is not a constructor

和ECMAScript

Arrow functions are like built-in functions in that both lack .prototype and any [[Construct]] internal method. So new (() => {}) throws a TypeError but otherwise arrows are like functions:

根据经验,任何没有原型的功能都不是新的.

在周围工作

简而言之,并不是每个函数都是构造函数,TypeScript通过要求new(){}来捕获它.然而,用户定义的函数是构造函数.

要解决这个问题,最简单的方法是将Fn声明为变量,并将其转换为构造函数.

interface FnType {}
var Fn: {new(): FnType} = (function() {}) as any

class B extends Fn {}

推理不相容

DISCALIMER:我不是一个TypeScript核心贡献者,只是一个TS风扇,有几个与TS有关的项目.所以这个部分是我个人的猜测.

TypeScript是一个起始于 2012 的项目,当ES2015在暗暗中仍然隐约出现时. TypeScript没有一个很好的参考类语义.

此后,TypeScript的 main goal 与ES3 / 5保持兼容.因此,在TypeScript中新增功能是合法的,因为它在ES3 / 5中也是合法的.同时,TypeScript还旨在捕获编程错误.扩展函数可能是一个错误,因为该函数可能不是一个明智的构造函数(例如,一个仅用于副作用的函数).延伸甚至不存在于ES3 / 5!所以TypeScript可以自由地定义自己的扩展使用,使得扩展必须与类变量配对.这使得TypeScript更加TypeSafe,与JavaScript兼容.

现在,ES2015规格定稿. JavaScript还有一个扩展关键字!然后不兼容来了有 efforts 解决不兼容.然而,仍然存在问题. ()=> void或函数类型不能是可扩展的,如上所述,由于内置函数.以下代码将中断

var a: (x: string) => void = eval
new a('booom')

另一方面,如果将ConstructorInterface引入到TypeScript中,并且实现了每个函数文字,则会出现向后的不兼容性.以下代码现在编译,但是当引入了ConstructorInterface时

var a = function (s) {}
a = parseInt // compile error because parseInt is not assignable to constructor

当然,TS团队可以有一个平衡这两个选项的解决方案.但这不是一个重中之重.另外,如果salsa,TS供电的JavaScript的代号完全实现.这个问题自然就会解决.

http://stackoverflow.com/questions/34576731/inherit-es6-ts-class-from-non-class


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Master Switch

The Master Switch

Tim Wu / Knopf / 2010-11-2 / USD 27.95

In this age of an open Internet, it is easy to forget that every American information industry, beginning with the telephone, has eventually been taken captive by some ruthless monopoly or cartel. Wit......一起来看看 《The Master Switch》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具