Javascript 如何确保给定键和值的对象类型的类型安全性?
鉴于这一类型:Javascript 如何确保给定键和值的对象类型的类型安全性?,javascript,flowtype,Javascript,Flowtype,鉴于这一类型: type Obj = $ReadOnly<{| foo: string, bar: number |}>; 但是字符串不能写入条,也不能将数字写入foo。现在,$ElementType定义似乎没有正确地找到与传递的键对应的类型,$ElementType的结果是数字和字符串。这是因为Keys返回所有可能键值的并集,而ElementType返回所有可能值的交集 type Obj = $ReadOnly<{| foo: string, bar: numbe
type Obj = $ReadOnly<{|
foo: string,
bar: number
|}>;
但是
字符串
不能写入条
,也不能将数字
写入foo
。现在,$ElementType
定义似乎没有正确地找到与传递的键对应的类型,$ElementType
的结果是数字和字符串
。这是因为Keys
返回所有可能键值的并集,而ElementType返回所有可能值的交集
type Obj = $ReadOnly<{| foo: string, bar: number |}>;
{
let k: 'foo' = 'foo';
// Works because Flow knows `k` is exactly `foo` and its value can only be a string.
let v: $ElementType<Obj, typeof k> = 'wow';
};
{
let k: $Keys<Obj> = 'foo';
// ERROR: Flow can't know `typeof k` is exactly `foo` and not also `bar`.
let v: $ElementType<Obj, typeof k> = 'wow';
};
获得所需行为的一种潜在方法是使用泛型。也就是说,看起来
在解决上述问题之前,我认为使用any
是合理的。它是相对隔离的,不会泄漏到您的功能之外
{
const setKeyValue = (key: $Keys<Obj>) =>
(value: $ElementType<Obj, typeof key>) =>
update(({[key]: value}: any));
};
{
const setKeyValue=(键:$Keys)=>
(值:$ElementType)=>
更新(({[key]:value}:any));
};
正如票证中提到的,在类型安全中有一些方法可以做到这一点,Flow会理解,但它们更详细
{
const setKeyValue = (key: $Keys<Obj>) => {
return {
foo: (value) => update(({[key]: value})),
bar: (value) => update(({[key]: value})),
}[key]; // using an object here is helpful in case you forget a field or if one is added later, Flow will error.
};
};
{
const setKeyValue=(键:$Keys)=>{
返回{
foo:(value)=>update(({[key]:value})),
bar:(value)=>update(({[key]:value})),
}[key];//在此处使用对象有助于防止您忘记某个字段,或者如果以后添加了某个字段,则流将出错。
};
};
当Flow不能确定某件事时,它通常会出错。如果不能确定,TypeScript通常是静默的
也就是说,在TypeScript中,以下内容不会出错,但应该是正确的
interface Obj { foo: string; bar: number; }
const update = (u: Partial<Obj>) => (obj: Obj): Obj => ({...obj, ...u});
const setKeyValue = <TKey extends keyof Obj>(key: TKey) =>
(value: Obj[TKey]) => update({[key]: {'crazy': 'crazy stuff that should error'}})
const w: Obj = {foo: 'hello', bar: 5};
setKeyValue('foo')('world')(w);
接口对象{foo:string;bar:number;}
常量更新=(u:Partial)=>(obj:obj):obj=>({…obj,…u});
const setKeyValue=(key:TKey)=>
(value:Obj[TKey])=>update({[key]:{'crazy':'crazy stuff that should error'})
const w:Obj={foo:'hello',bar:5};
setKeyValue('foo')('world')(w);
$ElementType
的结果是数字和字符串
。这是因为Keys
返回所有可能键值的并集,而ElementType返回所有可能值的交集
type Obj = $ReadOnly<{| foo: string, bar: number |}>;
{
let k: 'foo' = 'foo';
// Works because Flow knows `k` is exactly `foo` and its value can only be a string.
let v: $ElementType<Obj, typeof k> = 'wow';
};
{
let k: $Keys<Obj> = 'foo';
// ERROR: Flow can't know `typeof k` is exactly `foo` and not also `bar`.
let v: $ElementType<Obj, typeof k> = 'wow';
};
获得所需行为的一种潜在方法是使用泛型。也就是说,看起来
在解决上述问题之前,我认为使用any
是合理的。它是相对隔离的,不会泄漏到您的功能之外
{
const setKeyValue = (key: $Keys<Obj>) =>
(value: $ElementType<Obj, typeof key>) =>
update(({[key]: value}: any));
};
{
const setKeyValue=(键:$Keys)=>
(值:$ElementType)=>
更新(({[key]:value}:any));
};
正如票证中提到的,在类型安全中有一些方法可以做到这一点,Flow会理解,但它们更详细
{
const setKeyValue = (key: $Keys<Obj>) => {
return {
foo: (value) => update(({[key]: value})),
bar: (value) => update(({[key]: value})),
}[key]; // using an object here is helpful in case you forget a field or if one is added later, Flow will error.
};
};
{
const setKeyValue=(键:$Keys)=>{
返回{
foo:(value)=>update(({[key]:value})),
bar:(value)=>update(({[key]:value})),
}[key];//在此处使用对象有助于防止您忘记某个字段,或者如果以后添加了某个字段,则流将出错。
};
};
当Flow不能确定某件事时,它通常会出错。如果不能确定,TypeScript通常是静默的
也就是说,在TypeScript中,以下内容不会出错,但应该是正确的
interface Obj { foo: string; bar: number; }
const update = (u: Partial<Obj>) => (obj: Obj): Obj => ({...obj, ...u});
const setKeyValue = <TKey extends keyof Obj>(key: TKey) =>
(value: Obj[TKey]) => update({[key]: {'crazy': 'crazy stuff that should error'}})
const w: Obj = {foo: 'hello', bar: 5};
setKeyValue('foo')('world')(w);
接口对象{foo:string;bar:number;}
常量更新=(u:Partial)=>(obj:obj):obj=>({…obj,…u});
const setKeyValue=(key:TKey)=>
(value:Obj[TKey])=>update({[key]:{'crazy':'crazy stuff that should error'})
const w:Obj={foo:'hello',bar:5};
setKeyValue('foo')('world')(w);
Hm,我本以为我的setKeyValue
调用是可以静态分析的。为什么不能将setKeyValue('foo')
中的key
类型从$Keys
流到字符串
?嗯,我原以为我的setKeyValue
调用是可以静态分析的。为什么不能将setKeyValue('foo')
中的键的类型从$Keys
流到字符串
?