如何覆盖 Next.js `*.svg` 模块声明?

问题描述 投票:0回答:3
reactjs typescript next.js nextjs-image
3个回答
10
投票

替换

next-env.d.ts
的另一种方法是添加额外的声明文件,例如
additional.d.ts
,如https://nextjs.org/docs/basic-features/typescript中所述。

如文档中所述,此文件必须包含在

include
文件的
tsconfig.json
数组中,但我发现顺序也很重要 - 附加文件必须包含在 before
next-env.d.ts
之前。

这似乎是因为当包含默认导出的同一模块有多个声明时,第一个声明获胜。

// additional.d.ts
declare module "*.svg" {
  import React from "react";

  const content: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;

  export default content;
}
// tsconfig.json
{
  "include": ["additional.d.ts", "next-env.d.ts"] // The order matters!
}

这给出了我们首选的 SVG 类型,同时保留了

next-env.d.ts
的其他所需行为。

这似乎比简单地替换内置类型文件更好,因为下一个团队保留将来调整类型的权利,这意味着复制的类型需要手动保持最新,并且这种方法似乎没有记录的方法。


9
投票

我正在使用以下解决方法:

  • 添加

    next-env.d.ts
    以排除
    tsconfig.json
    中的数组:

    {
      // ...
      "exclude": ["node_modules", "next-env.d.ts"]
    }
    
  • next-env.d.ts
    添加到
    .gitignore
    /
    .eslintignore

  • 创建新文件

    custom.d.ts
    :

    /// <reference types="next" />
    /// <reference types="next/types/global" />
    
    // additional things that one used to put here before Next.js v11
    
  • 创建新文件

    images.d.ts
    :

    type StaticImageData = {
      src: string;
      height: number;
      width: number;
      placeholder?: string;
    };
    
    declare module '*.png' {
      const content: StaticImageData;
      export default content;
    }
    
    declare module '*.svg' {
      const content: React.FC<React.SVGProps<SVGSVGElement>>;
      export default content;
    }
    
    declare module '*.jpg' {
      const content: StaticImageData;
      export default content;
    }
    
    declare module '*.jpeg' {
      const content: StaticImageData;
      export default content;
    }
    
    declare module '*.gif' {
      const content: StaticImageData;
      export default content;
    }
    
    declare module '*.webp' {
      const content: StaticImageData;
      export default content;
    }
    
    declare module '*.ico' {
      const content: StaticImageData;
      export default content;
    }
    
    declare module '*.bmp' {
      const content: StaticImageData;
      export default content;
    }
    
  • 确保这些文件按照

    include
    tsconfig
    数组中指定的模式进行处理。

  • 如果您在

    *.avif
    中使用
    next@12
    ,也请添加它们的声明:

    declare module '*.avif' {
      const content: StaticImageData
      export default content
    }
    

0
投票

我尝试了很多方法来覆盖 Next 的

'*.svg'

我注意到,如果我手动将

'*.svg'
的自定义声明编辑到
next-env.d.ts
before
<reference>
指令中,它确实有效。但是,我无法让覆盖与单独文件中的自定义声明一起使用。在我的例子中,
include
中的文件顺序似乎并不重要。我什至从我的 tsconfig 包含中删除了
next-env.d.ts
,并且仅在自定义声明
'*.svg'
之后才将其导入。这不起作用。

最终完成的工作是创建一个third文件,例如

types.d.ts
看起来像这样:

/// <reference types="../overrides.d.ts" />
/// <reference types="../next-env.d.ts" />

现在在我的

overrides.d.ts
中,我添加了我的自定义声明:

declare module '*.svg' {
  const url: string;
  export default url;
}

最后我的

tsconfig.json
只包含
types.d.ts
:

...
  "include": [
    "types.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ]
...
© www.soinside.com 2019 - 2024. All rights reserved.