You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何传入库的实例在instanceof校验中返回false?(无继承场景)

ssh2 Client实例instanceof校验返回false的原因与解决

问题场景

使用TypeScript开发依赖ssh2的工具库时,编写了支持接收ssh2的Client实例或ConnectConfig配置对象的runCommand函数:

import { Client, ConnectConfig } from 'ssh2';

export function runCommand(params: Client | ConnectConfig) {
  if(params instanceof Client) {
    // 处理已有Client实例的逻辑
  } else {
    // 创建新Client并执行命令的逻辑
  }
}

编译后在消费代码中调用时,传入的Client实例始终无法通过instanceof校验(返回false):

const { readFileSync } = require("fs");
const { Client } = require("ssh2");
const { runCommand } = require("myLib");
const conn = new Client();

conn
  .on("ready", () => {
    console.log("Client :: ready");
    runCommand(conn); // 传入的conn无法通过instanceof校验
  })
  .connect({
    host: "example.com",
    port: 22,
    username: "me",
    privateKey: readFileSync(process.env.HOME + "/.ssh/id_ed25519"),
  });

工具库编译后的核心逻辑片段:

const ssh2_1 = require("ssh2");
//...
function runCommand(params) {
    if (params instanceof ssh2_1.Client) {
        // 处理逻辑
    }
    else {
       // 创建新Client的逻辑
    }
}

原因分析

这不是TypeScript编译问题,核心原因是Node.js的模块解析机制导致工具库和消费端加载了两个独立的ssh2包实例:

  • 工具库的ssh2是安装在自身node_modules目录下的私有依赖
  • 消费端的ssh2是安装在项目根目录node_modules下的依赖
  • JavaScript中instanceof的校验依赖构造函数的引用一致性,两个不同包中的Client类是完全独立的构造函数,因此消费端创建的实例无法匹配工具库中的ssh2_1.Client

解决方案

1. 将ssh2声明为peer依赖

修改工具库的package.json,把ssh2从dependencies移到peerDependencies,强制消费端提供统一版本的ssh2:

{
  "peerDependencies": {
    "ssh2": "^x.y.z" // 填写兼容的版本范围
  }
}

这样工具库会直接复用消费端安装的ssh2版本,确保Client构造函数的引用一致。

2. 替换instanceof校验逻辑

如果无法修改依赖声明,可以通过其他方式识别Client实例:

  • 检查构造函数名称:
if (params.constructor.name === 'Client') {
  // 处理逻辑
}
  • 检查实例的特征方法/属性:
if (typeof params.connect === 'function' && typeof params.on === 'function') {
  // 处理逻辑
}
  • 使用Object.prototype.toString判断类型:
if (Object.prototype.toString.call(params) === '[object Client]') {
  // 处理逻辑
}

内容的提问来源于stack exchange,提问作者Kerim Güney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 02:23:17