我正在尝试创造一个界面
export interface MenuItem {
title: string;
component?: any;
click?: any;
icon: string;
}
是否有方法要求组件或单击进行设置 是否有一种方法要求两个属性都不能设置?
我正在尝试创造一个界面
export interface MenuItem {
title: string;
component?: any;
click?: any;
icon: string;
}
是否有方法要求组件或单击进行设置 是否有一种方法要求两个属性都不能设置?
当前回答
只是延伸到上面的酷答案!对于登陆这里的人,同时寻找一个需要能力的部分版本!这里有一个片段,我要采取!
PartialReq
你想要一个接口的部分,但同时需要一些字段!这是如何做到的
export type PartialReq<T, Keys extends keyof T = keyof T> =
Pick<Partial<T>, Exclude<keyof T, Keys>>
& {
[K in Keys]: T[K]
};
使用的例子
export interface CacheObj<SigType = any, ValType = any> {
cache: Map<SigType, ValType>,
insertionCallback: InsertionCallback<SigType, ValType> // I want this to be required
}
// ...
export class OneFlexibleCache<SigType = any, ValType = any> {
private _cacheObj: CacheObj<SigType, ValType>;
constructor(
cacheObj: PartialReq<CacheObj<SigType, ValType>, 'insertionCallback'> // <-- here
// i used it
) {
cacheObj = cacheObj || {};
this._cacheObj = {
// ...
// _______________ usage
this._caches.set(
cacheSignature,
new OneFlexibleCache<InsertionSigType, InsertionValType>({
insertionCallback // required need to be provided
})
);
在这里你可以看到它工作得很完美
如未提供要求
更新:对于我在这里暗示的用法,一个更好的答案
我刚从医生那里找到了奥米特。
https://www.typescriptlang.org/docs/handbook/utility-types.html#omittk
我是来加的。但在此之前,我看到了一个很酷的答案。它涵盖了所有:
https://stackoverflow.com/a/48216010/7668448
看看吧!它展示了如何为所有不同版本的Typescript做这件事!为了不重复!去看看!
其他回答
有一个更简单的解决方案。不需要依赖任何 复杂条件类型(见答案):
是否有方法要求组件或单击进行设置?(包容或)
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: {} } // ✔
联合类型(|)对应于包含或。它与非条件属性相交。
使用in操作符将值缩小到其中一个组成部分:
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。
对于已接受的答案,MenuItemXor的此异或条件是不可能的。
操场上
从技术上讲,道具?:从来没有决心去支持?:未定义,尽管former常用于说明。
最后我这样做了:
export interface MenuItem {
title: string;
icon: string;
}
export interface MenuItemComponent extends MenuItem{
component: any;
}
export interface MenuItemClick extends MenuItem{
click: any;
}
然后我用了:
appMenuItems: Array<MenuItemComponent|MenuItemClick>;
但希望有一种方法可以用单一界面来建模。
还有另一个解决方案:
type RequiredKeys<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
type MenuItem2 = RequiredKeys<MenuItem, "component" | "click">;
只是延伸到上面的酷答案!对于登陆这里的人,同时寻找一个需要能力的部分版本!这里有一个片段,我要采取!
PartialReq
你想要一个接口的部分,但同时需要一些字段!这是如何做到的
export type PartialReq<T, Keys extends keyof T = keyof T> =
Pick<Partial<T>, Exclude<keyof T, Keys>>
& {
[K in Keys]: T[K]
};
使用的例子
export interface CacheObj<SigType = any, ValType = any> {
cache: Map<SigType, ValType>,
insertionCallback: InsertionCallback<SigType, ValType> // I want this to be required
}
// ...
export class OneFlexibleCache<SigType = any, ValType = any> {
private _cacheObj: CacheObj<SigType, ValType>;
constructor(
cacheObj: PartialReq<CacheObj<SigType, ValType>, 'insertionCallback'> // <-- here
// i used it
) {
cacheObj = cacheObj || {};
this._cacheObj = {
// ...
// _______________ usage
this._caches.set(
cacheSignature,
new OneFlexibleCache<InsertionSigType, InsertionValType>({
insertionCallback // required need to be provided
})
);
在这里你可以看到它工作得很完美
如未提供要求
更新:对于我在这里暗示的用法,一个更好的答案
我刚从医生那里找到了奥米特。
https://www.typescriptlang.org/docs/handbook/utility-types.html#omittk
我是来加的。但在此之前,我看到了一个很酷的答案。它涵盖了所有:
https://stackoverflow.com/a/48216010/7668448
看看吧!它展示了如何为所有不同版本的Typescript做这件事!为了不重复!去看看!
不是用一个接口,因为类型没有条件逻辑,不能相互依赖,但你可以通过分离接口:
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;