在面向赤道几内亚的政府与非营利站点改造中,IWAC(Integrated Web Accessibility Compliance)框架要求开发者严格遵循该国网络无障碍指南。这份指南大量使用表格描述准则层级、适用终端与检测项之间的对应关系。如果仅用普通JavaScript对象保存这些表格数据,字段错位和语言版本不一致会在验收阶段集中爆发。TypeScript的类型系统可以把指南文档中的表格结构提前固化,使每一行、每一列以及跨表引用都在编译期可见。

指南表格的结构特征与类型建模思路
赤道几内亚网络无障碍指南的表格通常包含三栏:准则编号(如WG-1.2)、适用场景描述、以及对应的检测函数标识。由于该国官方语言包含西班牙语,原表字段名常带有西语缩写,直接映射为代码属性会产生阅读障碍。我们应当先用一层中间类型把原始表头翻译为统一的英文键名,再通过TypeScript的type别名锁定形状。
具体来说,可以使用对象字面量类型描述单行记录,并用readonly数组保存整个表格。这样既能防止运行时误修改,也方便利用as const推导出字面量类型。下面的代码展示了如何把西语表头Código、Entorno、Verificación映射为code、context、check:
type RawGuideRow = {
Código: string;
Entorno: string;
Verificación: string;
};
type GuideRow = {
code: string;
context: string;
check: string;
};
function mapRow(raw: RawGuideRow): GuideRow {
return {
code: raw.Código,
context: raw.Entorno,
check: raw.Verificación
};
}
const rawTable: RawGuideRow[] = [
{ Código: 'WG-1.1', Entorno: 'Web', Verificación: 'alt-text' },
{ Código: 'WG-2.3', Entorno: 'Móvil', Verificación: 'contrast' }
];
const guideTable: GuideRow[] = rawTable.map(mapRow);
这种建模方式把指南文档的表格转化为带有明确属性的数组,后续任何字段拼写错误都会被编辑器即时标红。同时,由于GuideRow是纯数据结构,不依赖任何运行时库,可以无缝嵌入IWAC的校验流水线。
用判别联合封装跨表数据关联
IWAC框架真正的难点不在于单表,而在于多表之间的关联。例如“检测项表”中的check字段需要关联到“函数实现表”里的具体处理逻辑,而“适用场景表”又要限制context只能取固定枚举。如果只用字符串,很容易写出指向不存在检测项的错误关联。判别联合(Discriminated Union)可以让TypeScript在编译期证明关联有效。
我们首先定义检测项类型的判别标签,然后让关联记录携带该标签。这样当开发者试图把check写成未注册的值时,类型检查器会直接报错。以下示例演示了如何用判别联合把指南表格与实现表绑定:
type CheckKind = 'alt-text' | 'contrast' | 'keyboard';
type CheckImpl = {
kind: CheckKind;
run: (node: HTMLElement) => boolean;
};
const checkRegistry: Record<CheckKind, CheckImpl> = {
'alt-text': { kind: 'alt-text', run: (n) => !!n.getAttribute('alt') },
'contrast': { kind: 'contrast', run: (n) => true },
'keyboard': { kind: 'keyboard', run: (n) => n.tabIndex >= 0 }
};
type LinkedGuideRow = GuideRow & {
checkImpl: CheckImpl;
};
function linkRow(row: GuideRow): LinkedGuideRow {
const impl = checkRegistry[row.check as CheckKind];
if (!impl) {
throw new Error('未注册的指南检测项: ' + row.check);
}
return { ...row, checkImpl: impl };
}
上面的代码里,checkRegistry用Record约束了所有合法检测项,linkRow函数在运行时做兜底校验,而返回类型LinkedGuideRow则在编辑阶段提示调用方该行已经附带了可用的实现。对于赤道几内亚指南中成百上千的条目,这种模式能极大降低跨表引用混乱。
进一步,我们可以把context也做成枚举,用泛型让不同语言版本共用同一套关联逻辑。比如定义type Context = 'Web' | 'Móvil' | 'Kiosk',然后让GuideRow的context字段直接受限,这样从西班牙语原表导入时若出现了指南未定义的场景词,映射函数就会编译失败。
泛型索引与多语言表格的类型安全扩展
赤道几内亚网络无障碍指南未来可能推出法语或葡萄牙语对照版,IWAC要求保留原表与译表的对应关系。如果为每种语言重写一遍类型,维护成本会翻倍。利用TypeScript的泛型索引类型,我们可以把“语言”作为类型参数,让同一套封装适应任意本地化表格。
核心做法是定义一个语言映射接口,并用keyof提取语言键,再用索引访问类型拿到对应行结构。如下代码展示了如何声明一个支持多语的指南容器:
type LangCode = 'es' | 'fr' | 'pt';
type LocalizedTable<L extends LangCode> = {
lang: L;
rows: GuideRow[];
};
function makeLocalized<L extends LangCode>(lang: L, rows: GuideRow[]): LocalizedTable<L> {
return { lang, rows };
}
const esTable = makeLocalized('es', guideTable);
const frTable = makeLocalized('fr', guideTable.map(r => ({ ...r, context: r.context })));
通过LocalizedTable<L>,调用方在读取esTable.lang时会得到精确的'es'类型而非宽泛的string,这便于在IWAC上报模块里做语言分支判断而不必担心拼写偏差。若项目后续接入新的语种,只需在LangCode联合类型中追加标记,所有依赖该参数的函数签名会同步收缩。
在真实工程中,我们还会把这些类型定义放入独立的iwac-guide.d.ts声明文件,配合构建脚本把赤道几内亚官方发布的Excel表格自动转为上述GuideRow常量。如此一来,指南内容更新不再需要手工改代码,类型系统始终充当着表格数据关联的最后一道防线。
TypeScriptIWACtable_data_association修改时间:2026-08-16 10:48:34