Flow中与TypeScript Record工具类型等价的类型是什么?
Flow中等价TypeScript Record工具类型的方案
嘿,我懂你纠结的点——TypeScript的Record<KeyType, Value>和Flow里直接写{ [key: KeyType]: Value }确实有明显的语义差异,尤其是当KeyType是字符串/数字字面量的联合类型时。
先说说两者的核心区别
- 在TS里,
Record<'a' | 'b', number>会生成一个必须包含a和b两个键、值全为number类型、且不允许额外键的严格对象类型。 - 但Flow里的
{ [key: 'a' | 'b']: number }是个开放的索引签名:它只约束“如果对象有a或b键,值必须是number”,但不要求这两个键必须存在,甚至还允许添加其他类型的键——这显然和TS的Record语义完全不符。
解决方案:用Flow的映射类型实现等价语义
从Flow 0.104版本开始,Flow支持和TS几乎一致的映射类型语法,这就是实现TS Record等价类型的最佳方式:
// 先定义一个通用的Record类型(和TS的用法对齐) type Record<KeyType: string | number | symbol, Value> = { [key in KeyType]: Value }; // 举个实际例子 type Permission = Record<'read' | 'write' | 'delete', boolean>; // 这个类型等价于手动写: type Permission = { read: boolean, write: boolean, delete: boolean };
低版本Flow的兼容方案
如果你的项目还在使用不支持映射类型的旧版Flow,可以用$Exact结合$ObjMap来模拟:
import type { $ObjMap } from 'flow-typed'; type Record<KeyType, Value> = $Exact<$ObjMap<{ [key: KeyType]: mixed }, () => Value>>; // 使用方式完全一致 type Permission = Record<'read' | 'write' | 'delete', boolean>;
额外说明:如果不需要强制所有键存在
要是你想要的是“所有存在的键都属于KeyType,值都是Value,允许缺失部分KeyType的键,但不允许额外键”,那可以用$Exact<{ [key: KeyType]: Value }>——这对应TS里Partial<Record<KeyType, Value>>的语义。
内容的提问来源于stack exchange,提问作者wcandillon
相关产品推荐
相关产品推荐

