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

TypeScript中如何覆盖其他文件导入的函数?解决只读属性报错

Fixing "can't assign to getPerson because it is a read-only property" in TypeScript

The Problem

You've exported a function getPerson directly from msq.ts:

// msq.ts
export function getPerson(): Promise<{ name: string, id: number }> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ name: "manas", id: 2 });
    }, 5000);
  })
}

When you try to reassign this function in app.ts, TypeScript throws an error saying it's a read-only property:

// app.ts
import * as msq from "../msq";
// ❌ Error: can't assign to getPerson because it is a read-only property
msq.getPerson = function():Promise<{name:string,id:number}>{
  return Promise.resolve({name:"manas",id:2});
}

Why This Happens

ES modules treat direct exports (like export function) as read-only bindings. This is part of the official module specification—top-level exports can't be reassigned after being imported.

Solutions

1. Wrap the Function in an Exported Object (Best for Non-Testing Scenarios)

The cleanest fix is to export your function as a property of an object instead of a top-level export. Object properties are mutable, so you can modify them freely:

Update msq.ts:

// msq.ts
export const api = {
  getPerson(): Promise<{ name: string, id: number }> {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ name: "manas", id: 2 });
      }, 5000);
    });
  }
};

Then in app.ts:

// app.ts
import { api } from "../msq";
// ✅ No error—we're modifying an object property
api.getPerson = function(): Promise<{ name: string, id: number }> {
  return Promise.resolve({ name: "manas", id: 2 });
};

2. Use Type Assertion to Bypass Read-Only Check (Not Recommended)

If you can't modify msq.ts for some reason, you can use a type assertion to tell TypeScript to treat the export as writable. This skips type safety, so only use this for temporary debugging or edge cases:

// app.ts
import * as msq from "../msq";

// Cast the module to a mutable type to bypass checks
(msq as { getPerson: () => Promise<{ name: string, id: number }> }).getPerson = () => {
  return Promise.resolve({ name: "manas", id: 2 });
};

⚠️ Warning: This bypasses TypeScript's compile-time checks. If you mismatch the function signature, you'll get runtime errors instead of helpful warnings.

3. Mock the Function for Testing (If Using Jest/Vitest)

If you're trying to mock this function for tests, use your testing framework's built-in mocking tools instead of manual reassignment. For example, with Jest:

// app.test.ts
import * as msq from "../msq";

// Mock the module while preserving other original exports
jest.mock("../msq", () => ({
  ...jest.requireActual("../msq"),
  getPerson: jest.fn(() => Promise.resolve({ name: "manas", id: 2 }))
}));

// Use the mocked function in tests
test("uses mocked getPerson", async () => {
  const result = await msq.getPerson();
  expect(result).toEqual({ name: "manas", id: 2 });
});

This is the standard approach for testing and doesn't require changing your original module structure.


内容的提问来源于stack exchange,提问作者manas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:32:45