【问题标题】:Getting type error with changing syntax from require to import将语法从 require 更改为 import 时出现类型错误
【发布时间】:2021-11-21 08:20:34
【问题描述】:

将语法从 require, CommonJS 更改为 import, ES Module 时出现错误。

我尝试使用 Node.js、TypeScript、MySQL 创建一个待办事项应用程序。

首先,我编写了以下代码。

// db.ts
export {};
const mysql = require('mysql2');

const pool = mysql.createPool({
  host: 'localhost',
  user: 'user',
  password: 'password',
  database: 'db',
});

module.exports = pool;
//index.ts
import express from 'express';
import { Express, Request, Response } from 'express';
import { QueryError, RowDataPacket } from 'mysql2';
const pool = require('./db');

const app: Express = express();

app.get("/todos", async (req: Request, res: Response) => {
  await pool.promise().query(
    'SELECT * FROM todo'
  )
  .then((rows: RowDataPacket[]) => {
    res.json(rows[0]);
  })
  .catch((error: QueryError) => {
    throw error;
  })
});

这些代码运行良好。没有错误。 但是,使用 import 而不是 require 会给我带来错误。

//db.ts
import { createPool } from 'mysql2';

export const pool = createPool({
  host: 'localhost',
  user: 'user',
  password: 'password',
  database: 'db',
});
//index.ts
import express from 'express';
import { Express, Request, Response } from 'express';
import { QueryError, RowDataPacket } from 'mysql2';
import { pool } from '.db';

const app: Express = express();

app.get("/todos", async (req: Request, res: Response) => {
  await pool.promise().query(
    'SELECT * FROM todo'
  )
  .then((rows: RowDataPacket[]) => {
    res.json(rows[0]);
  })
  .catch((error: QueryError) => {
    throw error;
  })
});

我收到以下错误。

Argument of type '(rows: RowDataPacket[]) => void' is not assignable to parameter of type '(value: [RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader, FieldPacket[]]) => void | PromiseLike<...>'.
  Types of parameters 'rows' and 'value' are incompatible.
    Type '[RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader, FieldPacket[]]' is not assignable to type 'RowDataPacket[]'.
      Type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader | FieldPacket[]' is not assignable to type 'RowDataPacket'.
        Type 'RowDataPacket[]' is not assignable to type 'RowDataPacket'.
          The types of 'constructor.name' are incompatible between these types.
            Type 'string' is not assignable to type '"RowDataPacket"'.

为什么我有这个错误? 我认为使用requireimport 提供相同的功能,所以我很困惑。


额外信息

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

【问题讨论】:

    标签: mysql node.js typescript express


    【解决方案1】:

    只需指定您获得帮助的结果集的确切类型(.query(...).query&lt;RowDataPacket[]&gt;(...))。

    (我还将async.then 的混合匹配更改为await。)

    app.get("/todos", async (req: Request, res: Response) => {
      const resp = await pool.promise().query<RowDataPacket[]>(
        'SELECT * FROM todo'
      );
      res.json(resp[0]);
    });
    

    我猜mysql2 的类型在require 的情况下非常松散,所以你从来没有真正验证它们。

    为了完整起见,这是成功进行类型检查的完整单文件测试程序。

    import express from 'express';
    import { Express, Request, Response } from 'express';
    import { RowDataPacket, createPool } from 'mysql2';
    
    const pool = createPool({
      host: 'localhost',
      user: 'user',
      password: 'password',
      database: 'db',
    });
    
    const app: Express = express();
    
    app.get("/todos", async (req: Request, res: Response) => {
      const resp = await pool.promise().query<RowDataPacket[]>(
        'SELECT * FROM todo'
      );
      res.json(resp[0]);
    });
    

    【讨论】:

    • 感谢您的回答!另外,我误解了async.then 哈哈
    猜你喜欢
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 2014-05-17
    • 2021-12-03
    相关资源
    最近更新 更多