我从 Node.JS 堆栈上的 TypeScript 开始,我注意到在使用 require
时导入类时,TypeScript 在未定义方法(或属性)时不会出现编译错误。
我预期的错误是 TS2551: Property 'undefinedMethod' does not exist on type 'typeof MyClass'. Did you mean 'definedMethod'?
, 但它编译得很好。
然后当我尝试运行 server.ts
时, 我得到 TypeError: MyClass.undefinedMethod is not a function
作为常规的 JavaScript 错误。
如果我使用 import {MyClass} from './MyClass';
导入类的语法(并将 MyClass
更改为 export class MyClass
),然后 TypeScript 正确地提示 MyClass.undefinedMethod
未定义。
我无法使用 import
语法,因为我需要能够包含 MyClass
在浏览器客户端和我的 Node.JS 服务器上(具体见文末)。
如何让 TypeScript 在访问类的未定义方法的代码上显示编译错误?
这是我试过的代码:
MyClass.ts
(这只是我想在 script.ts
和 server.ts
中使用的基本类):
class MyClass {
static definedMethod () :void {
console.log('defined');
}
}
if (typeof module !== 'undefined') {
module.exports = MyClass;
}
server.ts
:(我只包含了关于 MyClass
的相关部分,还有一些关于 express
的其他内容):
const MyClass = require('./MyClass');
// import MyClass = require('./MyClass'); // TS2306: File '[PATH]/source/MyClass.ts' is not a module.
// import {MyClass} from './MyClass'; // TS2306: File '[PATH]/source/MyClass.ts' is not a module.
MyClass.definedMethod();
MyClass.undefinedMethod(); // No compiliation error.
script.ts
:
/// <reference path="../MyClass.ts" />
MyClass.definedMethod();
MyClass.undefinedMethod(); // Throws correctly TS2551: Property 'undefinedMethod' does not exist on type 'typeof MyClass'. Did you mean 'definedMethod'?
tsconfig.json
:
{
"compilerOptions": {
"outDir": "./dist",
"module": "umd",
"target": "es5",
"moduleResolution": "node"
},
"include": [
"source/**/*"
]
}
我真的不知道是什么allowSyntheticDefaultImports
和 esModuleInterop
做,但我尝试将它们添加到我的 tsconfig.json
, 它仍然没有用。
目录结构:
-
[dist]
-
[source]
-
[public]
-
script.ts
-
-
MyClass.ts
-
server.ts
-
-
tsconfig.json
关于为什么我不能改变的细节 require
至 import
:
如果我使用 import
和 export
语法,我的 server.ts
有效,但我无法使用 /// <reference path=
在我的 script.ts
因为错误TS2304: Cannot find name 'MyClass'.
如果我只是改用 import
在 server.ts
, 我得到 TS2306: File '[PATH]/source/MyClass.ts' is not a module.
最佳答案
when using require to import classes, TypeScript doesn't have a compilation error when methods (or properties) aren't defined.
与 const MyClass = require('./MyClass');
, MyClass
得到一个 any
类型。 any
选择退出类型检查,因此您实际上可以在其上调用任何内容。也就是说,因为 require
的类型签名看起来像 this :
interface NodeRequireFunction {
(id: string): any;
}
How can I get TypeScript to show a compile error on code that accesses an undefined method of a class?
首先,再次更改为 ES import-syntax 以启用类型检查 server.ts
:
// MyClass.ts
export class MyClass { ... }
// server.ts
import { MyClass } from './MyClass'
创建模块 global.ts
(你也可以把它放在 MyClass.ts
中),分配 MyClass
类到浏览器中的属性 Window
全局范围:
import { MyClass } from "./MyClass";
// augment global type declarations inside a module with "declare global"
declare global {
// browser window interface
interface Window {
// we want the class constructor (not instance) type, hence typeof MyClass
MyClass: typeof MyClass;
}
}
// this is the actual run-time assignment
window.MyClass = MyClass;
作为副作用,将此文件导入模块根目录的顶部:
// root.ts
import "./global"
在script.ts
, 删除三斜杠指令 /// <reference path="../MyClass.ts" />
(我们不再需要那种类型了)。例如。在将所有模块与 Webpack & Co. 捆绑在一起并使用 bundle 和 script.ts
之后脚本,你现在应该可以写:
window.MyClass.definedMethod()
希望对您有所帮助。
关于javascript - 访问 require-d 类的未定义方法时没有 TypeScript 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59204385/