在构建面向希腊 public sector 的 Web 应用时,开发团队必须遵循当地的网络无障碍指南,其中针对非文本内容(non-text content)的分类与替代信息要求比 WCAG 更为细致。IWAC(Integrated Web Accessibility Checker)提供了一套检查接口,但其默认数据模型并未区分希腊规范里的图标、信息图、装饰元素等类型。使用 TypeScript 不仅能让前端在编译期捕获错误的无障碍属性赋值,还能把指南条文转成强类型的封装层,方便在多框架中复用。

希腊指南中非文本内容的类型划分与TS建模
希腊网络无障碍指南将非文本内容拆分为多个语义子类:纯装饰性图像、具有传达功能的标准图标、包含数据的图表、以及音视频流中的非文本轨道等。每一类在替代文本(alt)、ARIA role、以及 lang 属性上都有不同约束。例如装饰性内容必须标为 aria-hidden="true" 且不提供可读 alt,而信息图表则需要长描述链接与希腊语摘要。
在 TypeScript 中,我们首先用枚举固化这些类型,避免字符串散落导致拼写错误。随后定义统一的接口,把指南中的“必须有”“不能有”转化为字段的可选与必填。下面代码展示了基础建模:
export enum GrNonTextType {
Decorative = 'decorative',
Icon = 'icon',
Chart = 'chart',
MediaTrack = 'media_track'
}
export interface NonTextBase {
type: GrNonTextType;
lang?: string;
}
export interface DecorativeContent extends NonTextBase {
type: GrNonTextType.Decorative;
ariaHidden: true;
alt?: never;
}
export interface IconContent extends NonTextBase {
type: GrNonTextType.Icon;
alt: string;
ariaHidden?: false;
}
export interface ChartContent extends NonTextBase {
type: GrNonTextType.Chart;
alt: string;
longDescUrl: string;
lang: string;
}
上述代码利用可辨识联合(discriminated union)确保编译器能根据 type 字段收窄对象结构。当开发者试图给装饰性内容加上 alt 时,由于 alt?: never 的设定,TS 会直接报错,从而在编码阶段拦截希腊指南明确禁止的行为。
进一步,我们可以把不同类别的校验函数也纳入类型系统,使用类型守卫(type guard)在运行时与编译期双重保障。这样在对接 IWAC 的 JSON 上报格式时,就能减少人工核对条文的负担。
封装IWAC适配层与泛型约束实现
IWAC 的扫描接口通常接收一组带有元数据的 DOM 节点描述。我们需要把上一节的强类型模型映射为 IWAC 期望的弱类型 payload。这里使用泛型函数封装转换逻辑,并约束输入必须符合希腊指南子类之一。
下面的适配器展示如何通过泛型与类型守卫,把内部模型序列化为 IWAC 可识别的对象,同时自动补全指南要求的默认属性(如装饰元素强制 aria-hidden):
import { GrNonTextType, NonTextBase } from './model';
function isDecorative(x: NonTextBase): x is DecorativeContent {
return x.type === GrNonTextType.Decorative;
}
export function toIWACPayload<T extends NonTextBase>(item: T): Record<string, unknown> {
if (isDecorative(item)) {
return {
kind: 'non_text',
category: item.type,
ariaHidden: true
};
}
const base = {
kind: 'non_text',
category: item.type,
alt: (item as any).alt,
lang: item.lang ?? 'el'
};
if (item.type === GrNonTextType.Chart) {
return { ...base, longDesc: (item as ChartContent).longDescUrl };
}
return base;
}
该封装让业务代码只需关心语义分类,而不必记忆 IWAC 字段名。泛型 T extends NonTextBase 保证传入对象至少携带 type,而具体子类型由联合模型保障。若未来指南修订新增子类型,编译器会提示我们在 toIWACPayload 中补充分支,避免遗漏。
在真实工程中,我们还可将适配层发布为独立 npm 包,配合 ESLint 规则限制直接写 aria-hidden 字面量,强制走封装函数。这种架构思考能显著降低跨项目合规成本,尤其适合同时维护多个希腊语站点的团队。
在React与Vue中的调用示例及常见误区
很多团队在接入时容易把“装饰性”与“图标”混淆:希腊指南规定纯 UI 分割线、背景纹理为装饰,而代表“购物车”“搜索”的 SVG 属于图标,必须提供希腊语 alt。下面 React 组件演示如何基于封装类型安全渲染:
import { GrNonTextType, IconContent } from './model';
import { toIWACPayload } from './adapter';
const searchIcon: IconContent = {
type: GrNonTextType.Icon,
alt: 'Αναζήτηση',
lang: 'el'
};
export function SearchButton() {
const payload = toIWACPayload(searchIcon);
console.log(payload);
return <button aria-label={searchIcon.alt}><svg role="img"></svg></button>;
}
Vue 场景下,可在 setup 中构造同类型对象并绑定至自定义指令,指令内部调用 toIWACPayload 向 IWAC 注入元数据。注意不要在模板里直接写未经验证的 alt,应通过 TypeScript 对象流入,防止自然语言描述与代码脱离。
常见误区之一是为图表同时写 alt 与 longDescUrl 但 lang 错填 en,希腊检查器会判定为未提供母语长描述。通过 ChartContent 接口将 lang 设为必填,能在编写阶段消除此类问题。另一个坑是装饰内容忘了标 aria-hidden,我们的 DecorativeContent 接口以 ariaHidden: true 固化该要求,从根本减少人工疏忽。
TypeScriptIWAC非文本内容修改时间:2026-08-16 08:12:18