入门
要安装 Deepkit 的运行时类型系统,需要两个包:Deepkit Type 编译器和 Deepkit Type 包本身。类型编译器是一个 TypeScript 变换器,用于从 TypeScript 类型生成运行时类型信息。Type 包包含运行时虚拟机和类型注解,以及许多用于处理类型的实用函数。
安装
npm install --save @deepkit/type npm install --save-dev @deepkit/type-compiler typescript ts-node
默认不会生成运行时类型信息。必须在 tsconfig.json
文件中设置 "reflection": true
才能启用。
如果要使用装饰器,必须在 tsconfig.json
中启用 "experimentalDecorators": true
。这对使用 @deepkit/type
并非绝对必要,但对其他 Deepkit 库的某些功能以及 Deepkit 框架是必要的。
文件:tsconfig.json
{ "compilerOptions": { "module": "CommonJS", "target": "es6", "moduleResolution": "node", "experimentalDecorators": true }, "reflection": true }
编写你的第一段带有运行时类型信息的代码:
文件:app.ts
import { cast, MinLength, ReflectionClass } from '@deepkit/type'; interface User { username: string & MinLength<3>; birthDate?: Date; } const user = cast<User>({ username: 'Peter', birthDate: '2010-10-10T00:00:00Z' }); console.log(user); const reflection = ReflectionClass.from<User>(); console.log(reflection.getProperty('username').type);
使用 ts-node
运行它:
./node_modules/.bin/ts-node app.ts
交互式示例
这是一个 codesandbox 示例: https://codesandbox.io/p/sandbox/deepkit-runtime-types-fjmc2f?file=index.ts
类型编译器
TypeScript 本身不允许通过 tsconfig.json
配置类型编译器。必须直接使用 TypeScript 编译器 API,或者使用像 Webpack 配合 ts-loader 这样的构建系统。为避免这种不便,Deepkit 类型编译器在安装 @deepkit/type-compiler
后会自动将自身安装到 node_modules/typescript
中(这是通过 NPM 的 install hooks 完成的)。
这使得所有访问本地安装的 TypeScript(即 node_modules/typescript
中的那个)的构建工具都能自动启用类型编译器。这使得 tsc、Angular、webpack、ts-node 和其他一些工具能够自动与 Deepkit 类型编译器一起工作。
如果类型编译器未能成功自动安装(例如因为 NPM install hooks 被禁用),可以使用以下命令手动完成:
node_modules/.bin/deepkit-type-install
请注意,如果本地 typescript 版本已更新(例如 package.json 中的 typescript 版本发生了变化并运行了 npm install
),必须运行 deepkit-type-install
。
Webpack
如果你希望在 webpack 构建中使用类型编译器,可以使用 ts-loader
包(或任何支持注册 transformer 的 TypeScript loader)。
文件:webpack.config.js
const typeCompiler = require('@deepkit/type-compiler'); module.exports = { entry: './app.ts', module: { rules: [ { test: /\.tsx?$/, use: { loader: 'ts-loader', options: { // 这将启用 @deepkit/type 的类型编译器 getCustomTransformers: (program, getProgram) => ({ before: [typeCompiler.transformer], afterDeclarations: [typeCompiler.declarationTransformer], }), } }, exclude: /node_modules/, }, ], }, }