我正在尝试创建一个可以
export interface MenuItem {
title: string;
component?: any;
click?: any;
icon: string;
}
组件
或单击
进行设置
匿名用户
有一个更简单的解决方案。无需依赖任何或复杂的条件类型(参见答案):
- 有没有办法要求设置组件或单击?(包含
OR
)
type MenuItemOr = {
title: string;
icon: string;
} & ({ component: object } | { click: boolean })
// brackets are important here: "&" has precedence over "|"
let testOr: MenuItemOr;
testOr = { title: "t", icon: "i" } // error, none are set
testOr = { title: "t", icon: "i", component: {} } // ✔
testOr = { title: "t", icon: "i", click: true } // ✔
testOr = { title: "t", icon: "i", click: true, component: {} } // ✔
联合类型(|
)对应于inclusive或
。它与非条件属性相交。
使用运算符中的将值缩小到其中一个成分:
if ("click" in testOr) testOr.click // works
type MenuItemXor = {
title: string;
icon: string;
} & (
| { component: object; click?: never }
| { component?: never; click: boolean }
)
let testXor: MenuItemXor;
testXor = { title: "t", icon: "i" } // error, none are set
testXor = { title: "t", icon: "i", component: {} } // ✔
testXor = { title: "t", icon: "i", click: true } // ✔
testXor = { title: "t", icon: "i", click: true, component: {} } //error,both set
基本上可以设置组件
或单击
,不应同时添加另一个组件。TS可以从MenuItemXor
中生成一个有区别的联合类型,它对应于XOR
。
这个XOR
条件对于MenuItemXor
来说是不可能的。
游戏场
1从技术上讲,prop?:从来没有
被解析为prop?:未定义的
,尽管前者经常用于说明。
不使用单个接口,因为类型没有条件逻辑,也不能相互依赖,但您可以通过拆分接口:
export interface BaseMenuItem {
title: string;
icon: string;
}
export interface ComponentMenuItem extends BaseMenuItem {
component: any;
}
export interface ClickMenuItem extends BaseMenuItem {
click: any;
}
export type MenuItem = ComponentMenuItem | ClickMenuItem;
借助于TypeScript 2.8中添加的Exclude
类型,提供了一种要求至少一组属性中的一个属性的通用方法:
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> =
Pick<T, Exclude<keyof T, Keys>>
& {
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>
}[Keys]
要求提供一个且仅提供一个的部分但非绝对方式是:
type RequireOnlyOne<T, Keys extends keyof T = keyof T> =
Pick<T, Exclude<keyof T, Keys>>
& {
[K in Keys]-?:
Required<Pick<T, K>>
& Partial<Record<Exclude<Keys, K>, undefined>>
}[Keys]
下面是一个TypeScript游乐场链接,显示了两者的作用。
RequireOnlyOne
的警告是,TypeScript在编译时并不总是知道运行时存在的每个属性。所以很明显,RequireOnlyOne
无法阻止它不知道的额外属性。我提供了一个示例,说明了RequireOnlyOne
如何错过游乐场链接末尾的内容。
使用以下示例快速概述其工作原理:
interface MenuItem {
title: string;
component?: number;
click?: number;
icon: string;
}
type ClickOrComponent = RequireAtLeastOne<MenuItem, 'click' | 'component'>
>
拾取
{[K in Keys]-?:必需
{
component: Required<{ component?: number }> & { click?: number },
click: Required<{ click?: number }> & { component?: number }
}[Keys]
这就变成了
{
component: { component: number, click?: number },
click: { click: number, component?: number }
}['component' | 'click']
最终变成
{component: number, click?: number} | {click: number, component?: number}
上述步骤1和步骤2的交点
{ title: string, icon: string}
&
({component: number, click?: number} | {click: number, component?: number})
简化为
{ title: string, icon: string, component: number, click?: number}
| { title: string, icon: string, click: number, component?: number}
问题内容: 我认为这个问题已经存在,但是我找不到。 我不明白,为什么必须要有一个功能接口才能使用lambda。考虑以下示例: 这可以正常工作,但是如果您取消注释行,则不会。为什么?以我的理解,编译器应该能够区分这两种方法,因为它们具有不同的输入参数。为什么我需要一个功能接口并炸毁我的代码? 编辑:链接的重复项没有回答我的问题,因为我在询问不同的方法参数。但是在这里,我得到了一些非常有用的答案,这要
我正在使用HIbernate core 3.6.2 final。我将注释类映射放在hibernate中。cfg。xml,例如 由于我使用3.6.2的Hibernate版本,所以我不需要创建注释配置类对象。因此,我将配置对象创建为私有静态最终SessionFactory SessionFactory; 但给我错误作为初始SessionFactory创建failed.org.hibernate.Map
我试图让VSCode启动并使用TypeScript运行,但收效甚微。 我正在看以下内容: https://code.visualstudio.com/docs/languages/typescript 看起来,一旦安装了编译器VSCode,就应该可以正常工作,但考虑到以下情况: tsconfig.json 包裹json tasks.json 项目 你好世界ts 从终端运行构建任务或tsc会正确指示
总之,是否可以有一个声明某些基属性但不限制其他属性的接口?这是我目前的情况: 我使用的是Flux模式,它定义了一个通用调度器: 然后,我用自己的有效负载类型创建一个调度程序,如下所示: 现在我有了一些动作代码,它应该分派一个带有一些附加数据的有效负载,但是< code>ActionPayload接口只允许< code>actionType。换句话说,这段代码: 给出编译错误,因为与接口不匹配。问题
我只想问关于争论的事。方法名并不重要,但每个方法都采用不同参数的唯一顺序,因此Oracle可以实现这个特性,而不是让每个“lambda-interface”都有一个方法。
而我用AndroidStudio2.3来调试,有什么问题吗?更重要的是,我的AndroidManifest是这样的。