描述
我创建了简单的类来在 TypeScript 中处理 1D 和 2D 向量。在其中我还添加了带有重载的“operator +”,以使其更方便工作:
class Vector1 {
static ["+"](vector: Readonly<Vector1>, scalar: number): Vector1;
static ["+"](first: Readonly<Vector1>, second: Readonly<Vector1>): Vector1;
static ["+"](arg1: Readonly<Vector1>, arg2: Readonly<Vector1> | number): Vector1 {
// Код не важен
return new Vector1();
}
x: number;
}
class Vector2 extends Vector1 {
static ["+"](vector: Readonly<Vector2>, scalar: number): Vector2;
static ["+"](first: Readonly<Vector2>, second: Readonly<Vector1>): Vector2;
static ["+"](first: Readonly<Vector2>, second: Readonly<Vector2>): Vector2;
static ["+"](arg1: Readonly<Vector2>, arg2: Readonly<Vector2> | Readonly<Vector1> | number): Vector2 {
// Код не важен
return new Vector2();
}
y: number;
}
这没有任何问题,它可以完美编译。但是,如果我尝试使用 JavaScript + JSDoc 编写相同的代码并启用类型检查......
class Vector1 {
/**
* @overload
* @param {Readonly<Vector1>} vector
* @param {number} scalar
* @returns {Vector1}
*/
/**
* @overload
* @param {Readonly<Vector1>} first
* @param {Readonly<Vector1>} second
* @returns {Vector1}
*/
/**
* @param {Readonly<Vector1>} arg1
* @param {Readonly<Vector1> | number} arg2
* @returns {Vector1}
*/
static ["+"](arg1, arg2) {
return new Vector1();
}
/** @type {number} */
x;
}
class Vector2 extends Vector1 {
/**
* @overload
* @param {Readonly<Vector2>} vector
* @param {number} scalar
* @returns {Vector2}
*/
/**
* @overload
* @param {Readonly<Vector2>} first
* @param {Readonly<Vector1>} second
* @returns {Vector2}
*/
/**
* @overload
* @param {Readonly<Vector2>} first
* @param {Readonly<Vector2>} second
* @returns {Vector2}
*/
/**
* @param {Readonly<Vector2>} arg1
* @param {Readonly<Vector2> | Readonly<Vector1> | number} arg2
* @returns {Vector2}
*/
static ["+"](arg1, arg2) {
return new Vector2();
}
/** @type {number} */
y;
}
...然后编译器有强烈的情绪:
类静态端“typeof Vector2”错误地扩展了基类静态端“typeof Vector1”。
属性“[”+”]”的类型不兼容。
类型 '{ (向量:只读,标量:数字):Vector2; (第一个:只读,第二个:只读):Vector2; (第一个:只读<...>,第二个:只读<...>):Vector2; }' 不可分配给类型 '{ (向量:只读,标量:数字):Vector1; (第一个:只读,第二个:只读):Vector1; }'。
参数“向量”和“向量”的类型不兼容。
“Readonly”类型中缺少属性“y”,但“Readonly”类型中需要属性“y”。ts(2417)
问题
- 到底有什么区别呢?毕竟,这两种情况的检查都是由 TS 编译器执行的。
- 如何解决这个问题呢?尽管如此,我还是不想放弃超载。
此外
配置:
{
"javascript.format.semicolons": "insert",
"javascript.inlayHints.enumMemberValues.enabled": true,
"javascript.inlayHints.variableTypes.enabled": true,
"javascript.inlayHints.propertyDeclarationTypes.enabled": true,
"javascript.updateImportsOnFileMove.enabled": "always",
"javascript.referencesCodeLens.enabled": true,
"javascript.referencesCodeLens.showOnAllFunctions": true,
"javascript.inlayHints.functionLikeReturnTypes.enabled": true,
"javascript.suggest.classMemberSnippets.enabled": false
"typescript.format.semicolons": "insert",
"typescript.preferences.importModuleSpecifier": "project-relative",
"typescript.implementationsCodeLens.enabled": true,
"typescript.referencesCodeLens.enabled": true,
"typescript.referencesCodeLens.showOnAllFunctions": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.inlayHints.enumMemberValues.enabled": true,
"typescript.inlayHints.functionLikeReturnTypes.enabled": true,
"typescript.inlayHints.propertyDeclarationTypes.enabled": true,
"typescript.inlayHints.variableTypes.enabled": true
"js/ts.implicitProjectConfig.checkJs": true,
"js/ts.implicitProjectConfig.target": "ESNext",
"js/ts.implicitProjectConfig.experimentalDecorators": true,
}
问题被证明是一个错误。
我在 GitHub 上提交了 Bug Ticket,微软确认了这个 Bug。
我会关注更新。如果有严重的问题,我会在回复中补充,如果我没忘记的话。 :)