Figma-Context-MCP TypeScript 类型定义详解:提升代码健壮性
引言:类型安全在Figma数据处理中的关键作用
在现代前端开发中,TypeScript(TS)已成为提升代码质量和开发效率的核心工具。对于Figma-Context-MCP这类需要处理复杂设计数据的中间件服务,类型系统不仅是代码规范的保障,更是数据流转可靠性的基石。本文将系统剖析项目核心类型定义,展示如何通过精准的类型设计解决Figma数据提取、转换、传输全流程中的常见问题。
核心类型架构概览
Figma-Context-MCP的类型系统采用分层设计,主要包含三大模块:
// 类型层次关系示意图(伪代码)
namespace FigmaMCP {
// 1. 原始数据类型:直接映射Figma API响应
export namespace Raw { /* ... */ }
// 2. 转换接口:定义数据处理契约
export namespace Transform { /* ... */ }
// 3. 服务类型:MCP服务器对外接口
export namespace Service { /* ... */ }
}
类型文件分布统计
| 文件路径 | 类型定义数量 | 主要类型类别 |
|---|---|---|
| src/extractors/types.ts | 12 | 设计数据提取相关 |
| src/mcp/tools/get-figma-data-tool.ts | 8 | API交互相关 |
| src/config.ts | 5 | 配置项相关 |
| src/services/figma.ts | 7 | 服务层接口 |
| 其他文件 | 15 | 工具函数与辅助类型 |
原始数据类型解析(Raw命名空间)
1. Figma节点类型体系
src/extractors/types.ts中定义了完整的Figma节点类型层次,核心接口如下:
export interface FigmaNodeBase {
id: string;
name: string;
type: NodeType;
x: number;
y: number;
width: number;
height: number;
visible?: boolean;
locked?: boolean;
parent?: FigmaNodeBase;
}
// 节点类型枚举
export enum NodeType {
DOCUMENT = "DOCUMENT",
CANVAS = "CANVAS",
FRAME = "FRAME",
GROUP = "GROUP",
RECTANGLE = "RECTANGLE",
TEXT = "TEXT",
// 共18种节点类型
}
设计亮点:通过NodeType枚举与泛型约束的组合,实现节点类型的精确区分:
// 类型守卫示例
export function isTextNode(node: FigmaNodeBase): node is TextNode {
return node.type === NodeType.TEXT;
}
// 泛型工具类型示例
export type NodeOfType<T extends NodeType> = Extract<FigmaNode, { type: T }>;
2. 样式属性类型设计
Figma样式系统的复杂性要求类型定义具备高度灵活性:
export interface PaintStyle {
type: 'SOLID' | 'GRADIENT_LINEAR' | 'GRADIENT_RADIAL' | 'GRADIENT_ANGULAR' | 'GRADIENT_DIAMOND' | 'IMAGE';
color?: RGBA;
gradientHandlePositions?: Vector2[];
gradientStops?: ColorStop[];
// 其他样式属性...
}
// 颜色类型的精确表示
export interface RGBA {
r: number; // [0, 1]
g: number; // [0, 1]
b: number; // [0, 1]
a: number; // [0, 1]
}
关键特性:使用联合类型而非单独接口表示不同绘画类型,既减少类型数量,又保持类型安全。
数据转换接口设计(Transform命名空间)
1. 提取器接口定义
design-extractor.ts中定义的核心转换契约:
export interface DesignExtractor<Input, Output> {
extract: (input: Input, options?: ExtractorOptions) => Promise<Output>;
validateInput: (input: unknown) => input is Input;
getVersion: () => string;
}
// 提取器配置选项
export interface ExtractorOptions {
depth?: number; // 递归提取深度,默认5层
includeHiddenNodes?: boolean; // 是否包含隐藏节点,默认false
nodeTypes?: NodeType[]; // 要提取的节点类型白名单
}
设计优势:通过泛型接口实现"输入验证-数据提取-版本控制"的完整契约,确保不同提取器实现的一致性。
2. 布局数据转换类型
Figma原始坐标系统到标准Web坐标的转换类型:
export interface TransformedLayout {
position: {
x: number;
y: number;
zIndex: number;
};
dimensions: {
width: number;
height: number;
aspectRatio: number;
};
constraints: {
horizontal: 'MIN' | 'CENTER' | 'MAX' | 'STRETCH';
vertical: 'MIN' | 'CENTER' | 'MAX' | 'STRETCH';
};
// 相对定位信息
relativeTo?: {
nodeId: string;
offset: { x: number; y: number };
};
}
解决痛点:Figma原始坐标与Web布局模型的差异通过该类型转换层统一,避免AI编码代理处理设计数据时的坐标混乱。
服务接口类型(Service命名空间)
1. MCP工具接口规范
mcp/tools/index.ts定义的工具服务接口:
export interface MCPTool<Params, Result> {
name: string;
description: string;
execute: (params: Params, context: ToolContext) => Promise<Result>;
parametersSchema: Zod.Schema<Params>; // 使用Zod进行运行时验证
}
// 工具执行上下文
export interface ToolContext {
requestId: string;
timestamp: number;
auth?: {
userId: string;
permissions: string[];
};
cache?: {
get: (key: string) => Promise<unknown | null>;
set: (key: string, value: unknown, ttl?: number) => Promise<void>;
};
}
创新点:将TypeScript静态类型与Zod运行时验证结合,实现"编译时+运行时"双重类型安全,特别适合MCP服务器这类需要处理外部输入的服务。
2. Figma数据工具专用类型
get-figma-data-tool.ts中的专用类型定义:
// 请求参数类型
export interface GetFigmaDataParams {
fileKey: string;
nodeId?: string;
version?: string;
format?: 'json' | 'svg' | 'png';
options?: {
includeStyles?: boolean;
includeComponents?: boolean;
includeTextContent?: boolean;
};
}
// 响应结果类型
export interface GetFigmaDataResult {
status: 'success' | 'error';
data?: TransformedFigmaDocument;
error?: {
code: string;
message: string;
details?: Record<string, unknown>;
};
metadata: {
extractedAt: number;
nodeCount: number;
extractionTimeMs: number;
};
}
类型安全保障:通过严格的请求/响应类型定义,防止AI代理传递无效参数或处理不完整响应。
实用类型工具与最佳实践
1. 常用工具类型
项目中定义的通用类型工具集合:
// 提取对象值类型
export type ValueOf<T> = T[keyof T];
// 使指定属性可选
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
// 排除空值类型
export type NonNullable<T> = T extends null | undefined ? never : T;
// 深度只读类型
export type DeepReadonly<T> = T extends object
? { readonly [P in keyof T]: DeepReadonly<T[P]> }
: T;
应用示例:在Figma数据缓存场景中的使用
// 将响应数据转为深度只读,防止意外修改
const cacheData: DeepReadonly<GetFigmaDataResult> = await fetchData(params);
// 部分更新配置选项
const partialOptions: PartialBy<ExtractorOptions, 'depth'> = {
includeHiddenNodes: true
};
2. 类型扩展模式
针对不同Figma插件扩展的类型扩展模式:
// 基础节点类型
export interface BaseNode {
id: string;
name: string;
type: NodeType;
// 核心属性...
}
// 扩展机制
export interface NodeExtension<T extends NodeType> {
type: T;
extensionData: Record<string, unknown>;
}
// 带扩展的具体节点类型
export type ExtendedFrameNode = BaseNode & FrameSpecificProperties & NodeExtension<'FRAME'>;
// 类型守卫辅助函数
export function isExtendedNode<T extends NodeType>(
node: BaseNode,
type: T
): node is BaseNode & NodeExtension<T> {
return node.type === type && 'extensionData' in node;
}
扩展性优势:这种模式允许第三方插件安全扩展节点类型,同时保持核心类型系统的稳定性。
类型系统在错误处理中的应用
1. 错误类型枚举
export enum FigmaMCPErrorType {
VALIDATION_ERROR = 'VALIDATION_ERROR',
EXTRACTION_ERROR = 'EXTRACTION_ERROR',
API_ERROR = 'API_ERROR',
CACHE_ERROR = 'CACHE_ERROR',
AUTH_ERROR = 'AUTH_ERROR',
RATE_LIMIT_ERROR = 'RATE_LIMIT_ERROR'
}
// 类型化错误类
export class FigmaMCPError extends Error {
type: FigmaMCPErrorType;
code: string;
details?: Record<string, unknown>;
constructor(
message: string,
type: FigmaMCPErrorType,
code: string,
details?: Record<string, unknown>
) {
super(message);
this.type = type;
this.code = code;
this.details = details;
this.name = 'FigmaMCPError';
}
}
错误处理改进:类型化错误系统使调用方能够精确捕获和处理特定错误类型,替代了传统的字符串匹配方式。
2. 结果类型模式
// 成功结果类型
export type SuccessResult<T> = {
success: true;
data: T;
};
// 失败结果类型
export type ErrorResult<E extends FigmaMCPError = FigmaMCPError> = {
success: false;
error: E;
};
// 结果联合类型
export type Result<T, E extends FigmaMCPError = FigmaMCPError> =
| SuccessResult<T>
| ErrorResult<E>;
// 使用示例
async function fetchFigmaData(params: GetFigmaDataParams): Promise<Result<TransformedFigmaDocument>> {
try {
// 实现...
return { success: true, data: transformedData };
} catch (e) {
return {
success: false,
error: e instanceof FigmaMCPError ? e : new FigmaMCPError(
'Unknown error',
FigmaMCPErrorType.EXTRACTION_ERROR,
'UNKNOWN'
)
};
}
}
优势:通过Result类型模式强制调用方显式处理成功和失败路径,避免JavaScript中常见的未捕获异常问题。
类型驱动开发实践
1. 类型覆盖率目标
Figma-Context-MCP采用严格的类型覆盖率标准:
| 文件类型 | 最低类型覆盖率 | 目标类型覆盖率 |
|---|---|---|
| 核心类型文件 | 100% | 100% |
| 工具实现文件 | 90% | 95% |
| 测试文件 | 80% | 90% |
通过TypeScript的noImplicitAny、strictNullChecks等严格模式选项,配合ESLint的@typescript-eslint/typedef规则确保类型覆盖率。
2. 类型文档自动生成
项目的类型定义同时作为API文档的来源:
/**
* 转换后的Figma文本节点数据
* @remarks
* 该类型包含文本内容、样式信息和布局数据,是AI编码代理生成UI组件的关键依据
* @example
* ```typescript
* const textNode: TransformedTextNode = {
* id: "1:2",
* name: "标题",
* type: "TEXT",
* content: "欢迎使用Figma-Context-MCP",
* style: {
* fontSize: 24,
* fontWeight: 600,
* fontFamily: "Inter",
* color: { r: 0, g: 0, b: 0, a: 1 }
* },
* layout: { /* ... * / }
* };
* ```
*/
export interface TransformedTextNode extends TransformedNode {
content: string;
style: TextStyle;
characters?: TextCharacter[]; // 逐字符样式信息
}
文档价值:通过TSDoc注释与类型定义结合,确保API文档与代码实现始终同步,避免传统文档"过时"问题。
高级类型应用:泛型工具函数
1. 节点过滤函数类型
// 通用节点过滤函数类型
export type NodeFilter<N extends FigmaNodeBase = FigmaNodeBase> = (
node: N,
index: number,
array: N[]
) => boolean;
// 创建带类型的过滤函数
export function createNodeFilter<N extends FigmaNodeBase>(
options: {
nodeTypes?: N['type'][];
minSize?: { width?: number; height?: number };
includeHidden?: boolean;
}
): NodeFilter<N> {
return (node) => {
// 实现过滤逻辑...
return true;
};
}
// 使用示例
const textFilter = createNodeFilter<TextNode>({
nodeTypes: ['TEXT'],
minSize: { width: 10, height: 10 }
});
const textNodes = allNodes.filter(textFilter);
类型优势:通过泛型约束,使过滤函数自动适应不同节点类型,同时保持类型安全。
2. 数据转换管道类型
// 转换管道类型定义
export type TransformPipeline<Input, Output> = Array<
(data: any) => any
> & {
input: Input;
output: Output;
};
// 创建类型安全的转换管道
export function createPipeline<Input, Output>(
transforms: Array<(data: any) => any>
): TransformPipeline<Input, Output> {
// 实现管道逻辑...
return Object.assign(transforms, {
input: {} as Input,
output: {} as Output
});
}
// 使用示例
const figmaDataPipeline = createPipeline<RawFigmaData, TransformedFigmaDocument>([
validateRawData,
extractLayoutData,
transformStyles,
enrichMetadata
]);
类型体操技巧:通过交叉类型(Intersection Type)为数组添加input/output类型标记,实现类型安全的数据转换管道。
类型系统演进与最佳实践
1. 版本化类型策略
随着Figma API的更新,类型定义需要持续演进:
// 版本化类型示例
export namespace FigmaV1 {
export interface FrameNode { /* v1版本Frame类型 */ }
}
export namespace FigmaV2 {
export interface FrameNode { /* v2版本Frame类型 */ }
}
// 兼容性处理
export type FrameNode = FigmaV2.FrameNode & {
// 向后兼容属性
legacyProperties?: FigmaV1.FrameNode;
};
版本管理优势:通过命名空间隔离不同版本的类型定义,确保API版本升级时的平滑过渡。
2. 类型优化 checklist
在添加新类型时,建议遵循以下检查清单:
- 是否使用了最小必要权限原则(最小接口)
- 是否考虑了空值安全(严格Null检查)
- 是否提供了类型守卫函数
- 是否添加了TSDoc注释
- 是否定义了配套的验证函数
- 是否考虑了与其他类型的互操作性
结语:类型驱动的Figma数据服务未来
Figma-Context-MCP的类型系统不仅是代码规范的集合,更是一套完整的数据处理哲学。通过本文介绍的类型设计模式,开发者可以构建出更健壮、更易维护、更具扩展性的Figma数据服务。随着AI编码代理的普及,精确的类型定义将成为设计与开发之间无缝协作的关键桥梁。
后续我们将推出《Figma-Context-MCP类型测试策略》,深入探讨如何通过类型测试确保Figma数据处理的准确性。敬请关注!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



