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

NextJS 14自定义全局声明使用及运行报错问题

NextJS中String全局原型方法运行报错问题解决

问题场景

在NextJS项目中,通过utils.d.ts为String添加全局原型方法stripHtml,TS配置已引入该文件,VS Code能正常识别类型,但运行dev命令时抛出TypeError: content.stripHtml is not a function错误。


相关代码

utils.d.ts
export {}

declare global {
  interface String {
    /**
     * Returns string after removing all html tags.
     */
    stripHtml(): string
  }
}
String.prototype.stripHtml = function (): string {
  return this.replace(/(<([^>]+)>)/gi, '')
}
tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "paths": {
      "@/*": ["./*"]
    },
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "include": ["utils.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
Example.tsx
import React from 'react'

interface Props {
  posts: Record<string, any>[]
}

const Example: React.FC<Props> = ({ posts }) => {
  return (
    <section>
      <div className="container">
        <div>
          {posts.map((item, idx) => {
            const post = item.attributes
            const { title, content } = post
            return (
              <div key={`post-${idx}`}>
                <div>
                  <h2>{title}</h2>
                  <p>{content.stripHtml()}</p>
                </div>
              </div>
            )
          })}
        </div>
      </div>
    </section>
  )
}

export default Example
报错信息
TypeError: content.stripHtml is not a function
    at eval (webpack-internal:///./components/Example.tsx:37:58)
    at Array.map (<anonymous>)
    at Example (webpack-internal:///./components/Example.tsx:21:40)
    at renderWithHooks (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5658:16)
    at renderIndeterminateComponent (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5731:15)
    at renderElement (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5946:7)
    at renderNodeDestructiveImpl (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6104:11)
    at renderNodeDestructive (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6076:14)
    at renderNode (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6259:12)
    at renderChildrenArray (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6211:7)
    at renderNodeDestructiveImpl (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6141:7)
    at renderNodeDestructive (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6076:14)
    at renderNode (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6259:12)
    at renderChildrenArray (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6211:7)
    at renderNodeDestructiveImpl (/Users/vickyvish/Projects/eweb-next/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6141:7)

解决办法

1. 确保原型方法代码被执行

NextJS启用isolatedModules后,每个文件会被当作独立模块处理,utils.d.ts中的原型方法实现不会自动运行。需要在项目入口文件(如pages/_app.tsx)手动导入该文件:

// pages/_app.tsx
import '../utils.d.ts'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

2. 拆分类型声明与实现(推荐)

将类型声明和运行时代码分离,符合TS文件规范:

  • 创建utils/stringExtensions.ts存放方法实现:
String.prototype.stripHtml = function (): string {
  return this.replace(/(&lt;([^&gt;]+)&gt;)/gi, '')
}
  • 修改utils.d.ts仅保留类型声明:
export {}

declare global {
  interface String {
    /**
     * Returns string after removing all html tags.
     */
    stripHtml(): string
  }
}

然后在_app.tsx中导入实现文件:

import '../utils/stringExtensions.ts'

3. 校验content的实际类型

确认接口返回的content确实是字符串类型,避免因类型不符导致报错,可添加类型守卫:

<p>{typeof content === 'string' ? content.stripHtml() : content}</p>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 08:00:31