gpt4 book ai didi

flowtype - 对象不能有键

转载 作者:行者123 更新时间:2023-12-04 13:22:16 25 4
gpt4 key购买 nike

我试图定义一个对象不能有某个键。

这是我的案例:

alert({
items: [{ label:'Apple' }, { label:'Orange' }]
})


alert({
items: [{ foo:'Apple' }, { foo:'Orange' }]
labelKey: 'foo'
})

如果items是一个不包含“label”键的对象数组,那么Options中需要labelKey

我试过这个:

type Options = {|
items: Array<{ label:string }>
|} | {|
items: Array<$Diff<{}, { label:string }>>,
labelKey: string // must be key in items
|}

function alert(options: Options) {

}

奖金问题:也可以定义 labelKey 是项目中传递的对象中的任意键吗?

最佳答案

确保对象上不存在属性

tl;dr: 使用 { myProp?: empty }

我假设您想使用 objects as maps当您将某些内容传递给 alert 函数时。创建没有标签的 map 的诀窍是提供一个属性,如果分配给某物,将无法进行类型检查。

我们可以利用 empty type ,一种不匹配任何东西的类型,以获得预期的效果。将 empty 类型与对象映射结合使用有点棘手,因为通过定义属性,我们告诉流我们希望该类型位于对象中。所以这无法进行类型检查:

( Try )

type MapWithLabel = {
[string]: string,
label: string,
}

type MapWithoutLabel = {[string]: mixed, label: empty}

type Options = {|
items: Array<MapWithLabel>
|} | {|
labelKey: string,
items: Array<MapWithoutLabel>,
|}

declare function alert(options: Options): void;

alert({
items: [{ foo:'Apple' }], // Error, expected a "label" property with empty type
labelKey: 'foo'
})

接下来,我们可以将属性定义为optional ,这意味着如果该属性存在,则仅对 empty 进行类型检查。有了这个,我们可以给对象一个“标签”属性:

  • 不存在或
  • 有一个不匹配的类型(空)

因此代码可以没有该属性的值(我们想要的),或者它可以传递空的东西(这是不可能的)。

( Try )

type MapWithLabel = {
[string]: string,
label: string,
}

type MapWithoutLabel = {[string]: mixed, label?: empty}

type Options = {|
items: Array<MapWithLabel>
|} | {|
labelKey: string,
items: Array<MapWithoutLabel>,
|}

declare function alert(options: Options): void;

alert({
items: [{ label:'Apple' }],
})

alert({
items: [{ label:'Apple' }], // Error - Should not have label
labelKey: 'ohno',
})

alert({
items: [{ foo:'Apple' }],
labelKey: 'foo'
})

alert({
items: [{ foo:'Apple' }], // Error - Needs a labelKey
})

因此,为了获得预期的效果,我们需要利用两个工具:可选属性和 empty 类型。有了它,我们可以指定一个对象,如果该 empty 属性存在,该对象将无法进行类型检查。

在类型级别设置动态属性键

tl;dr: 不可能

关于奖励问题:我不确定 Flow 能否理解这一点,因为我不知道在对象上设置变量属性的方法。我不希望有此功能,因为它会使事情变得复杂/无法进行类型检查。

编辑:经过更多研究,您可以使用indexer properties断言一个对象在类型级别有一个键:

(Try)

type ObjWithKey<T: string = 'label'> = {
// An indexer property with only one valid value: T with "label"
// as default, but we can't ensure that the property exists anymore
// and multiple indexers are not supported.
[T]: string,
aNumber: 3,
aFunction: () => void,
}

declare var usesLabel: ObjWithKey<>

(usesLabel.label: string);
(usesLabel.aNumber: number);
(usesLabel.missing: number); //Error - Doesn't exist on object
(usesLabel.aFunction: () => void);
(usesLabel.aFunction: string); //Error - Wrong type

但是,您不能这样做并且将该对象用作通用 map ,因为不支持多个索引器属性 (Try)。作为引用,其他人试图做其他类似的事情,but couldn't get it to work .

如果这对您来说是一个主要问题,请查看您是否可以以不同的方式构建您的数据结构,以便更轻松地使用 Flow 进行静态分析。

关于flowtype - 对象不能有键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49578103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com