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(/(<([^>]+)>)/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
相关产品推荐
相关产品推荐

