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 function 和 arrow 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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
- 面向对象:理解 Python 类的单继承与多继承
- java入门第二季--继承--java中的继承初始化顺序
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- 组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。