Итак, я протестировал замену вашей старой функции прототипа ES5 a
на новую ES6 class a
. Это вызывает ошибку:
Uncaught TypeError: конструктор класса a не может быть вызван без 'new'
Разверните этот фрагмент, чтобы проверить:
function declareClass(classModel, version) {
if (typeof classModel !== 'function') {
throw classModel + ' cannot be used as a class as it is not a function';
}
if(window.myClasses === undefined) {
window.myClasses = {};
}
window.myClasses[classModel.name] = classModel;
classModel.prototype._version = version || '1.0';
classModel.getVersion = function() {
return this.prototype._version;
};
};
function declareChildClass(subClass, superClass, version) {
declareClass(subClass, version);
if (typeof superClass !== 'function' && superClass !== null) {
throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
if (superClass) {
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
subClass.prototype._super = superClass.prototype;
};
(function() {
class a {
constructor(id, properties) {
this.id = id;
this.properties = properties
}
echo() {
console.log('ID [' + this.id + ']');
console.log('Properties');
console.log(this.properties);
}
}
window.declareClass(a, 'A1')
})();
(function() {
window.declareChildClass(b, window.myClasses.a, 'B2')
function b(id) {
window.myClasses.a.call(this, 'B' + id, {})
}
})();
var a = new window.myClasses.a('TestA', {data: 'test'}),
b = new window.myClasses.b('X');
a.echo();
b.echo();
Он происходит из этой строки: window.myClasses.a.call(this, 'B' + id, {}).
Поскольку myClasses.a
является классом ES6, он не поддерживает вызов без new
ключевые слова. К сожалению, внутри vanilla JS нет решения этой проблемы.
Но поскольку вы используете TS, вы можете установить цель транспиляции на ES5
, чтобы принудительно преобразовать блестящий синтаксис class
обратно в базовую функцию прототипа старой школы. Результат будет:
var a = /** @class */ (function () {
function a(id, properties) {
this.id = id;
this.properties = properties;
}
a.prototype.echo = function () {
console.log('ID [' + this.id + ']');
console.log('Properties');
console.log(this.properties);
};
return a;
}());
И эта ошибка исчезла, разверните этот фрагмент для проверки:
function declareClass(classModel, version) {
if (typeof classModel !== 'function') {
throw classModel + ' cannot be used as a class as it is not a function';
}
if(window.myClasses === undefined) {
window.myClasses = {};
}
window.myClasses[classModel.name] = classModel;
classModel.prototype._version = version || '1.0';
classModel.getVersion = function() {
return this.prototype._version;
};
};
function declareChildClass(subClass, superClass, version) {
declareClass(subClass, version);
if (typeof superClass !== 'function' && superClass !== null) {
throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
if (superClass) {
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
subClass.prototype._super = superClass.prototype;
};
(function() {
"use strict";
var a = /** @class */ (function () {
function a(id, properties) {
this.id = id;
this.properties = properties;
}
a.prototype.echo = function () {
console.log('ID [' + this.id + ']');
console.log('Properties');
console.log(this.properties);
};
return a;
}());
window.declareClass(a, 'A1')
})();
(function() {
window.declareChildClass(b, window.myClasses.a, 'B2')
function b(id) {
window.myClasses.a.call(this, 'B' + id, {})
}
})();
var a = new window.myClasses.a('TestA', {data: 'test'}),
b = new window.myClasses.b('X');
a.echo();
b.echo();
Заключение, да, вы можете смешать код TS со старым кодом JS и заставить их работать вместе. Но вам нужно немного изменить код TS, чтобы привести его в соответствие со старой парадигмой, например, вы не используете модуль в старом коде, а только глобальные переменные. Вы можете также отказаться от модуля в TS.
class a {
id:string;
properties:{};
constructor(id:string, properties:{}) {
this.id = id;
this.properties = properties
}
echo() {
console.log('ID [' + this.id + ']');
console.log('Properties');
console.log(this.properties);
}
}
;(window as any).declareClass(a, 'A1');
Или, если вы все еще предпочитаете использовать модуль, вам понадобится код моста на стороне TS.
bridgeCode.ts
import a from './myClassA.ts';
;(window as any).declareClass(a, 'A1');