使用vanilla JS对象和流程实施数据结构很简单:
type ExampleObjType = {
key1: number,
key2: string
};
const obj: ExampleObjType = {
key1: 123,
key2: '123'
};
这似乎需要一个不必要的大量样板来在Immutable中强制执行类似的结构:
type TestSpec = {
key1: number,
key2: string,
};
const TestRecord = Record({
key1: 0,
key2: '',
});
const record: TestSpec & Record<TestSpec> = new TestRecord({
key1: 123,
key2: '123',
});
此外,上述结构有一些主要缺点:
理想情况下,我可以使用Immutable.Map
,如下所示:
type TestSpec = Map<{key1: number, key2: number}>;
const testMap: TestSpec = Map({
key1: 123,
key2: '123',
});
但是,当前实现只允许键入键和值类型。我可以使用类似type Key = 'key1' | 'key2'
之类的东西约束键类型,但是我仍然不会明确键入每个键的值。
有没有办法用Immutable完成我正在寻找的东西?这似乎是真正的类型安全的基本要求,特别是当用于Redux动作有效载荷时。
答案 0 :(得分:6)
immutable.Record()
很难输入。实际上,it's currently typed要返回any
。一方面,这很不方便,因为您需要从头开始描述TestRecord
的类型。另一方面,它可以让你随心所欲地输入它!
这是一个选项:
interface TestSpec {
constructor(defaults: $Shape<TestSpec>): void,
key1: number,
key2: string,
};
const TestRecord: Class<TestSpec> = Record({
key1: 0,
key2: '',
});
Class<TestSpec>
类型是实例具有类型TestSpec
的类的类型。您不必在TestSpec
中定义构造函数,但通过这样做,Flow会确保obj
在new TestRecord(obj)
看到正确的时间。
(注意:$Shape<TestSpec>
是一个对象的类型,可能有也可能没有。所以在这种情况下它基本上意味着{key1?: number, key2?: string}
)
new TestRecord({key1: 123, key2: '123'}); // OK
new TestRecord({key1: 123}); // OK
new TestRecord({key2: '123'}); // OK
new TestRecord({key2: 123}); // Error number -> string
new TestRecord({key1: '123'}); // Error string -> number
new TestRecord({key1: 123, key2: '123', key3: 'blah'}); // Error unknown property key3
Flow将检查实例属性是否具有正确的类型
const record = new TestRecord({key1: 123, key2: '123'});
(record.key1: string); // Error number -> string
(record.key2: number); // Error string -> number