Contribute to this guide

guideCKEditor 5 中的 TypeScript 支持

CKEditor 5 是使用 TypeScript 构建的,并具有本机类型定义。使用 npm 分发的所有官方包都包含类型定义。

我们使用 TypeScript 5.0 构建所有包,但是,编辑器也应该与较旧的版本(例如 4.9)一起使用。TypeScript 并不遵循语义版本控制,因此请相应地测试您的代码。

使用 TypeScript 只是一种选择。如果您不需要它的功能,您可以继续在 JavaScript 中使用 CKEditor 5。

# 为什么要使用 CKEditor 5 与 TypeScript

使用 TypeScript 具有一些优势

  • 它有助于生成简洁且易于维护的代码。
  • 它为 CKEditor 5 API 引入了代码自动完成和类型建议。
  • 如果您正在开发自定义插件并密集地使用 CKEditor 5 框架,TypeScript 编译器将帮助您捕获常见的类型错误并提高代码质量。

# CKEditor 5 TypeScript 设置

与使用 JavaScript 环境相比,使用 TypeScript 时运行 CKEditor 5 并没有太大区别。您可以考虑使用类型断言或类型转换来满足 TypeScript 编译器。

# 运行编辑器

以下是经典编辑器类型初始化的示例

import { ClassicEditor } from 'ckeditor5'

const editorPlaceholder = document.querySelector( '#editor' ) as HTMLElement;

ClassicEditor
    .create( editorPlaceholder ).catch( error => {
        console.error( error );
    } );

# 用于 Angular、React 和 Vue 3 组件的类型

我们为 Angular、React 和 Vue 3 提供的最新版本的官方组件已迁移到 TypeScript,并使用 CKEditor 5 的本机类型定义。您不再需要提供自定义定义。您可以使用以下指南

# 使用 TypeScript 开发插件

CKEditor 5 的 API 非常广泛且复杂,但使用 TypeScript 可以让您更轻松地使用它。

您可以使用 包生成器 来搭建基于 TypeScript 的插件。

编写一个简单的插件类似于在普通 JavaScript 中编写它,但是您需要添加 TypeScript 增强 以向编译器提供有关插件的附加信息。

根据您的插件,增强以下接口

  • EditorConfig,它通知新插件扩展了配置。
  • PluginsMap,它通知提供了一个额外的插件;在使用 editor.plugins.get( '...' ) 时很有用。
  • CommandsMap,它通知提供了一个额外的命令;在使用 editor.commands.get( '...' ) 时很有用。

增强可以在包含编辑器设置的文件中放置。您也可以创建一个单独的文件(例如 augmentation.ts)并将其导入。

以下是我们 创建基本插件 教程中的一个示例,我们向其中添加了一个 UTC 配置选项。

import {
  ClassicEditor,
  Bold,
  Essentials,
  Heading,
  Italic,
  Paragraph,
  List,
  Plugin,
  ButtonView
} from 'ckeditor5';

import 'ckeditor5/ckeditor5.css';

declare module '@ckeditor/ckeditor5-core' {
    interface EditorConfig {
        timestamp?: { utc: boolean };
    }

    interface PluginsMap {
        [ Timestamp.pluginName ]: Timestamp;
    }
}

class Timestamp extends Plugin {
    public static get pluginName() {
        return 'Timestamp' as const;
    }

    public init(): void {
        const editor = this.editor;

        const utc = editor.config.get( 'timestamp.utc' );

        editor.ui.componentFactory.add( 'timestamp', () => {
            const button = new ButtonView();

            button.set( {
                label: 'Timestamp',
                withText: true
            } );

            button.on( 'execute', () => {
                const now = new Date();

                const date = utc ? now.toUTCString() : now.toString(); // If the configuration option is present, we show a UTC timestamp.

                editor.model.change( writer => {
                    editor.model.insertContent( writer.createText( date ) );
                } );
            } );

            return button;
        } );
    }
}

ClassicEditor
    .create( document.querySelector( '#editor' ) as HTMLElement, {
        plugins: [ Essentials, Paragraph, Heading, List, Bold, Italic, Timestamp ],
        toolbar: [ 'heading', 'bold', 'italic', 'numberedList', 'bulletedList', 'timestamp' ],
        timestamp: { utc: true } // This will be autocompleted and type checked thanks to our augmentation.
    } )
    .then( editor => {
        console.log( 'Editor was initialized', editor );
        console.log( editor.plugins.get( 'Timestamp' ) ); // This will have type Timestamp thanks to our augmentation.
    } )
    .catch( error => {
        console.error( error.stack );
    } );

# 添加非官方 JavaScript 插件

CKEditor 5 是一个 TypeScript 项目,CKEditor 5 提供的所有插件也使用 TypeScript。但是,有一些方法可以使用 JavaScript 包与编辑器一起使用。

# 社区类型

即使您要使用的包是 JavaScript,也可能已经存在您可以使用的类型。 Definitely Typed 是一个用于非类型化 npm 包的 TypeScript 定义的中央存储库。要为您的 JavaScript 包安装社区类型,请尝试以下命令

npm install --save-dev @types/<package-name>

如果您成功安装了这些类型,则无需执行任何操作。您应该不再看到 TypeScript 编译器错误,并且您的项目应该已准备好构建。

# 自定义声明

如果您创建了自定义插件,则社区类型将不可用。在这种情况下,您需要添加自定义定义。

首先,在您的项目中创建一个声明文件 .d.ts。例如,您可以将其放在 types/index.d.ts 中。然后在文件内部,按照以下示例定义模块。

// index.d.ts

declare module 'path' { // Module name.
  export function normalize( p: string ): string; // API exposed by the module.
  export function join( ...paths: any[] ): string;
}

最后,确保 TypeScript 编译器了解您的声明。将包含文件目录的路径放在 include 数组中。

// tsconfig.json

{
    "include": [ "./src", "./types" ],
    "compilerOptions": {
        // Compiler options.
        // ...
    }
    // More options.
    // ...
}

# 抑制错误

如果没有社区类型,并且创建声明不是一种选择,仍然有一种方法可以使用 JavaScript 包构建 TypeScript 项目。只需在 JavaScript 包上方添加一个保留的 TypeScript 注释。

// @ts-ignore
import { foo } from 'javascript-package';

此注释会抑制来自以下行的所有错误。