如何在 Typescript 文件中导入 Svelte 组件?

How do you import a Svelte component in a Typescript file?

是否可以在 Typescript 文件中导入 Svelte 组件并让 Rollup 成功编译它?

以下代码作为 Javascript 文件运行,但在转换为 Typescript 时出错,因为 TS 编译器不知道如何处理 .svelte 文件:

import Component from './Component.svelte';

const foo = () => new Component({ target: document.body });

是否有 rollup-plugin-svelte@rollup/plugin-typescript 的组合可以预处理 Svelte 组件,使 Typescript 编译器可以包含 Svelte 代码?


如果更多上下文有帮助,boardgame.io 包括 an in-browser debugging component built with Svelte, which is bundled in both a plain JS client & in a React client component, and we’re trying to update our Rollup config 正是针对这种情况。

尝试将 @tsconfig/svelte 添加到您的项目,然后更新您的 tsconfig.json 文件:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": ["src/**/*"],
  "exclude": ["node_modules/*", "__sapper__/*", "public/*"],
}

只是为了扩展 Rich 的回答,我很好奇地想调查为什么导入 Svelte 有助于某些设置。

the TS compiler doesn’t know how to handle a .svelte file

Svelte 通过在 svelte/types/runtime/ambient.d.ts:

中分发文件解决了这个问题(至少在撰写本文时的版本 3.35.0
declare module '*.svelte' {
    export { SvelteComponentDev as default } from 'svelte/internal';
}

这有效地使 TS 编译器分析 .svelte 个文件。出于学术兴趣,它还声明了 .svelte 文件中的脚本可以访问的所有运行时功能的类型,例如 set_attributes()(有关更多信息,请参见 svelte/internal)。所以只写 declare module '*.svelte' {} 只会让你完成一部分,因为你还需要那些运行时声明。

因此,要让 TypeScript 编译器处理 .svelte 文件,您需要以某种方式引用该文件的类型 svelte/types/runtime/ambient.d.ts。它实际上是由包的入口点类型文件间接引用的(在 Svelte 的 package.jsontypes 字段中指定的值),types/runtime/index.d.ts,因此同样,您可以引用该入口点类型文件。这样做将是最佳实践,因为它对目录结构中的未来重构具有鲁棒性。

扩展 @tsconfig/svelte/tsconfig.json 满足这一点,因为有问题的 tsconfig 文件通过其 compilerOptions.types 属性:

引用 "svelte" 节点模块
{
  // ... Omitted...

  "compilerOptions": {
    // ... Omitted...

    "types": ["svelte"]
  }
}

这实际上意味着编译上下文将包含此引用:

/// <reference types="svelte" />

您同样可以自己编写相同的行,尽管您也可以扩展 Svelte tsconfig,因为它对未来的 Svelte 发展很稳健。

针对副作用导入的建议出于同样的原因起作用:

import "svelte";

我发现即使我在扩展 Svelte tsconfig,也没有引用 Svelte 类型。结果是因为我在我的 tsconfig 中得到了这一行:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  
  // ... Omitted...

  "compilerOptions": {
    // ... Omitted...

    "types": ["node"] // This overrides ["svelte"]!
  }
}

我通过将 "types": ["node"] 替换为 "types": ["node", "svelte"] 来修复它。