javascript – 从非类继承ES6 / TS类

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

内容简介: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


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

查看所有标签

猜你喜欢:

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

世界因你不同

世界因你不同

李开复、范海涛 / 中信出版社 / 2010 / 29.8

这是李开复唯一的一本自传,字里行间,是岁月流逝中沉淀下来的宝贵的人生智慧和职场经验。捣蛋的“小皇帝”,11岁的“留学生”,奥巴马的大学同学,26岁的副教授,33岁的苹果副总裁,谷歌中国的创始人,他有着太多传奇的经历,为了他,两家最大的IT公司对簿公堂。而他的每一次人生选择,都是一次成功的自我超越。   透过这本自传,李开复真诚讲述了他鲜为人知的成长史、风雨兼程的成功史和烛照人生的心灵史,也首次全面......一起来看看 《世界因你不同》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具