@decaf-ts/decoration

中文文档
0.20.0发布于 2026/11/07MPL-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 2190

Decoration and metadata mechanisms for decaf-ts

原始使用文档
文档目录18 节
  1. @decaf-ts/decoration
  2. Core Concepts
  3. Metadata
  4. Storing and Retrieving Metadata
  5. Working with Property and Method Types
  6. Decoration
  7. Creating a Simple Decorator
  8. Creating a Flavoured Decorator
  9. Extending Decorators
  10. Utility Decorators
  11. @apply
  12. @propMetadata and @methodMetadata
  13. Related
  14. Social
  15. Getting help
  16. Contributing
  17. Supporting
  18. License

Banner

@decaf-ts/decoration

The decoration module provides a small, composable system for building and applying TypeScript decorators with flavour-aware resolution and a centralized runtime Metadata store. It lets you define base decorators, provide framework-specific overrides and extensions ("flavours"), and record/read rich metadata for classes and their members at runtime.

Core Concepts

  • Metadata: A centralized, static class for reading and writing metadata for classes and their members. It supports nested keys and can mirror metadata on the constructor for easy access.
  • Decoration: A builder class for creating and managing decorators. It allows you to define a base set of decorators and then override or extend them with different "flavours".
  • Flavours: A mechanism for providing framework-specific implementations of decorators. This allows you to create libraries that are agnostic of the underlying framework, and then provide specific implementations for different environments (e.g., Angular, React, Vue).
  • Decorators: A set of utility decorators (@metadata, @prop, @method, @param, @apply) for working with the metadata system.

Licence GitHub language count GitHub top language

Build & Test CodeQLSnyk Analysis Pages builder .github/workflows/release-on-tag.yaml

Open Issues Closed Issues Pull Requests Maintained

Forks Stars Watchers

Node Version NPM Version

Documentation available here

Minimal size: 5.6 KB kb gzipped

Description

@decaf-ts/decoration provides two complementary capabilities:

  • A small, builder-style API (Decoration) to define and apply decorators that can vary by "flavour" (for example, different frameworks or environments) while keeping a stable key-based API.
  • A centralized runtime Metadata store (Metadata) for reading and writing structured information about classes and their members, using reflect-metadata for design-time type hints.

This module aims to standardize how decorators are composed, discovered, and executed across contexts, and how metadata is stored and queried during runtime.

Main building blocks

  • Decoration (builder and registry)

    • You create a decoration pipeline for a key (for("component"), for example).
    • For the default flavour ("decaf"), you define the base decorators with define(...).
    • For other flavours (e.g., "vue", "nest"), you can either override the base decorators (define for that flavour) or extend them with extras (extend(...)).
    • At runtime, a global flavour resolver (setFlavourResolver) decides which flavour to apply to a given target. If that flavour has overrides, they are used; otherwise, the default base decorators are applied. Any flavour-specific extras and default extras are appended.
    • The result of apply() is a decorator function whose name encodes the flavour and key to aid debugging.
  • Decorator utilities

    • metadata(key, value): writes arbitrary metadata on a class or member.
    • prop(): captures the Reflect design:type for a property and records it in Metadata under properties..
    • apply(...decorators): composes multiple decorators of different kinds and applies them in sequence.
    • propMetadata(key, value): convenience factory that performs both metadata(key, value) and prop().
    • description(text): stores a human-friendly description for a class or property under description.class or description..
  • Metadata store

    • Static convenience API backed by a singleton instance. It maps each class constructor to a structured metadata object.
    • Keys are nested (e.g., "properties.name", "description.class") and navigated using a splitter (default ".").
    • When mirroring is enabled (default), the internal metadata object is also defined on the constructor under a stable, non-enumerable key (DecorationKeys.REFLECT) for quick inspection.
    • Helper methods:
      • properties(ctor): list known property names that have recorded type info.
      • description(ctor, prop?): read description for class or a property.
      • type(ctor, prop): read the recorded design type for a property.
      • get/set(ctor, key): low-level access to arbitrary paths.

Constants and types

  • DefaultFlavour: the default flavour identifier ("decaf").
  • ObjectKeySplitter: delimiter for nested metadata keys (".").
  • DecorationKeys: well-known metadata keys (REFLECT, PROPERTIES, CLASS, DESCRIPTION, design:type, etc.).
  • DefaultMetadata: the default metadata shape used as a base.
  • BasicMetadata / Constructor: utility types that describe metadata structure and a class constructor signature.

Design highlights

  • Composable and flavour-aware: The Decoration builder allows different environments or frameworks to contribute distinct decorator behavior under the same semantic key. This is useful when building adapters (e.g., Angular vs React components) without changing user code imports.
  • Predictable application order: Default decorators are applied first (or a flavour-specific override is used), followed by extras. Extras can come from the default flavour and/or the resolved flavour.
  • Introspectable metadata: The Metadata store makes it straightforward to record and query runtime facts about models, properties, and behavior. This is especially helpful for ORMs, serializers, validators, and UI bindings.

How to Use

This guide provides examples of how to use the main features of the @decaf-ts/decoration library.

Metadata

The Metadata class is a centralized store for runtime type information and other metadata.

Storing and Retrieving Metadata

You can use the @metadata decorator or the Metadata.set() and Metadata.get() methods to store and retrieve metadata for a class or its members.

import { metadata, Metadata } from '@decaf-ts/decoration';

@metadata('my-class-key', 'my-class-value')
class MyClass {
  @metadata('my-prop-key', 'my-prop-value')
  myProp: string;
}

// Retrieve metadata
const classMetadata = Metadata.get(MyClass, 'my-class-key'); // 'my-class-value'
const propMetadata = Metadata.get(MyClass, 'my-prop-key'); // 'my-prop-value'

Working with Property and Method Types

The @prop and @method decorators automatically capture design-time type information.

import { prop, method, Metadata } from '@decaf-ts/decoration';

class MyService {
  @prop()
  myProperty: string;

  @method()
  myMethod(param1: number): boolean {
    // ...
  }
}

// Retrieve type information
const propType = Metadata.type(MyService, 'myProperty'); // String
const returnType = Metadata.return(MyService, 'myMethod'); // Boolean
const paramTypes = Metadata.params(MyService, 'myMethod'); // [Number]

Decoration

The Decoration class allows you to create and manage decorators with different "flavours".

Creating a Simple Decorator

import { Decoration } from '@decaf-ts/decoration';

const myDecorator = Decoration.for('my-decorator')
  .define((target: any) => {
    console.log('My decorator was applied to', target.name);
  })
  .apply();

@myDecorator
class MyDecoratedClass {}

Creating a Flavoured Decorator

You can create different versions of a decorator for different "flavours".

import { Decoration, DefaultFlavour } from '@decaf-ts/decoration';

// Define the default decorator
const defaultDecorator = Decoration.for('my-flavoured-decorator')
  .define((target: any) => {
    console.log('Default decorator applied to', target.name);
  })
  .apply();

// Define a decorator for the 'vue' flavour
const vueDecorator = Decoration.flavouredAs('vue')
  .for('my-flavoured-decorator')
  .define((target: any) => {
    console.log('Vue decorator applied to', target.name);
  })
  .apply();

// Use the default decorator
@defaultDecorator
class MyDefaultClass {}

// Use the 'vue' decorator by setting the flavour
Decoration.setResolver(() => 'vue');

@defaultDecorator
class MyVueClass {}

Extending Decorators

You can extend an existing decorator with additional functionality.

import { Decoration } from '@decaf-ts/decoration';

const baseDecorator = Decoration.for('my-extended-decorator')
  .define((target: any) => {
    console.log('Base decorator applied');
  })
  .apply();

const extendedDecorator = Decoration.for('my-extended-decorator')
  .extend((target: any) => {
    console.log('Extended decorator applied');
  })
  .apply();

@extendedDecorator
class MyExtendedClass {}
// Console output:
// Base decorator applied
// Extended decorator applied

Utility Decorators

@apply

The @apply decorator allows you to apply multiple decorators to a single target.

import { apply } from '@decaf-ts/decoration';

const decorator1 = (target: any) => { console.log('Decorator 1'); };
const decorator2 = (target: any) => { console.log('Decorator 2'); };

@apply(decorator1, decorator2)
class MyMultipliedClass {}

@propMetadata and @methodMetadata

These decorators are shortcuts for applying metadata and capturing type information at the same time.

import { propMetadata, methodMetadata, Metadata } from '@decaf-ts/decoration';

class MyMetaClass {
  @propMetadata('my-key', 'my-value')
  myProp: string;

  @methodMetadata('my-method-key', 'my-method-value')
  myMethod() {}
}

const propMeta = Metadata.get(MyMetaClass, 'my-key'); // 'my-value'
const propType = Metadata.type(MyMetaClass, 'myProp'); // String
const methodMeta = Metadata.get(MyMetaClass, 'my-method-key'); // 'my-method-value'

Readme Card

Social

LinkedIn

Languages

TypeScript JavaScript NodeJS ShellScript

Getting help

If you have bug reports, questions or suggestions please create a new issue.

Contributing

I am grateful for any contributions made to this project. Please read this to get started.

Supporting

The first and easiest way you can support it is by Contributing. Even just finding a typo in the documentation is important.

Financial support is always welcome and helps keep both me and the project alive and healthy.

So if you can, if this project in any way. either by learning something or simply by helping you save precious time, please consider donating.

License

This project is released under the Mozilla Public License 2.0.

By developers, for developers...

版本与发布记录

@decaf-ts/decoration 共发布 67 个版本,首次发布于 2025/09/13;过去 12 个月发布了 33 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.20.0latest2026/11/076 天前
0.19.32026/09/201 个月前
0.19.22026/09/032 个月前
0.19.12026/09/032 个月前
0.19.02026/09/012 个月前
0.18.32026/07/303 个月前

关于 @decaf-ts/decoration 的常见问题

@decaf-ts/decoration 是什么?

Decoration and metadata mechanisms for decaf-ts

如何安装 @decaf-ts/decoration?

在项目目录运行 npm install @decaf-ts/decoration,或使用 pnpm add / yarn add / bun add。

@decaf-ts/decoration 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@decaf-ts/decoration 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@decaf-ts/decoration 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@decaf-ts/decoration 可以商用吗?

@decaf-ts/decoration 使用 MPL-2.0 许可。弱 Copyleft:可以商用,也可以和闭源代码一起使用;但如果分发时修改了 MPL 授权的文件,这些文件的修改需以 MPL 开源。以上为概括,不构成法律意见,请以许可原文为准。

@decaf-ts/decoration 的下载量有多少?

根据 npm 官方下载统计,@decaf-ts/decoration 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,190 次,日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@decaf-ts/decoration 还在维护吗?

最新版本 0.20.0 发布于 2026/11/07(6 天前);至今共发布 67 个版本,其中过去 12 个月发布了 33 个;首次发布于 2025/09/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。