javascript - 访问 require-d 类的未定义方法时没有 TypeScript 错误

标签 javascript node.js typescript

我从 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.tsserver.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/**/*"
  ]
}

我真的不知道是什么allowSyntheticDefaultImportsesModuleInterop做,但我尝试将它们添加到我的 tsconfig.json , 它仍然没有用。

目录结构:

  • [dist]
  • [source]
    • [public]
      • script.ts
    • MyClass.ts
    • server.ts
  • tsconfig.json

关于为什么我不能改变的细节 requireimport :

如果我使用 importexport语法,我的 server.ts有效,但我无法使用 /// <reference path=在我的 script.ts因为错误TS2304: Cannot find name 'MyClass'.

如果我只是改用 importserver.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/

相关文章:

typescript - JSON 模式的 anyOf 类型如何转换为 typescript ?

javascript - Angular HttpClient如何将结果传递给模板

javascript - 尝试从 <li> 中选择单个项目并将该值放入文本框中

javascript - 带有 expect 的 mocha 不适用于测试错误

javascript - 自定义文件上传脚本在 safari 中不起作用

javascript - 在 setTimeout 中执行操作时,Alexa Skill 响应没有显示任何内容

node.js - CouchDB 的反向代理卡在 Node.js 中的 POST 和 PUT 上

angular - ngx-datatable - 过滤列不能正常工作?

javascript - useState 不会使用 React Hooks 的 async/await 呈现 axios 调用的结果

Javascript字符串替换非数字和字母