typescript - 以一种方式实现接口,当一个类实现它时,它**必须**实现接口的所有属性,无论是可选的还是非可选的
问题描述
我想以一种方式实现接口,当一个类实现它时,它必须实现接口的所有属性,无论是可选的还是非可选的。
如果我有
interface Person {
name: string,
address?: string,
}
class Fisherman implements Person {
name: string;
fishingRodColor: string;
// and any more properties I want
}
打字稿不会引发错误,没关系Fisherman
不实现address
,因为它是可选的,但我确实希望它引发错误,我希望它强制我将Fisherman
类作为这两个选择之一:
class Fisherman implements Person {
name: string;
address?: string;
fishingRodColor: string;
// and any more properties I want
}
或者
class Fisherman implements Person {
name: string;
address: string;
fishingRodColor: string;
// and any more properties I want
}
两者都应该被允许,并且至少应该要求其中一种实现。
如果我只是简单地编写我的Person
界面而address
不是可选的
interface Person {
name: string,
address: string,
}
它不允许我编写我希望它允许我的这个类:
class Fisherman implements Person {
name: string;
address?: string;
fishingRodColor: string;
// and any more properties I want
}
因为它会说address
不能是可选的,因为它在Person
界面中不是可选的。
编辑:我感谢您的帮助,但我对解决方案的另一个需要是对于我的用例,如果address
是可选的,我希望能够声明这个const
对象:
const fisherman: Fisherman: {
name: 'George'
fishingRodColor: 'Red'
}
但是如果address: string | undefined
,typescript 仍然会引发一个错误,说fisherman
must have the property address
。打字稿要我这样做:
const fisherman: Fisherman: {
name: 'George'
fishingRodColor: 'Red'
address: undefined
}
但我不想(而且我认为我也不能在新的 Mongo 版本中,因为 undefined 已被弃用)将其中未定义的字段推送到我的数据库中。
我可以在插入数据库之前做一些变通方法,比如undefineds
在插入数据库之前删除,但是对于这个用例来说,使用接口可能不值得。
解决方案
您可以将所有带有类型的可选属性转换T
为T | undefined
:
type Complete<T> = {
[P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>> ? T[P] : (T[P] | undefined);
}
在您的示例中:
class FishermanError implements Complete<Person> {
name: string;
fishingRodColor: string;
// error: Property 'address' is missing
}
class Fisherman implements Complete<Person> {
name: string;
fishingRodColor: string;
address: string
// ok
}
class Fisherman2 implements Complete<Person> {
name: string;
fishingRodColor: string;
address: string | undefined
// ok
}
推荐阅读
- python-3.x - 向量化三次样条插值 Python
- python - 文件未从 python cgi 完全上传
- r - 将矩阵添加到小标题
- spring-boot - Spring Boot 响应实体返回空集
- javascript - 素材卡内容溢出图标栏
- javascript - 更改输入值后,JS仍然显示旧值
- swiftui - 如何为 SwiftUI 动态 VStack 项创建 UI 测试?
- c - Azure IoT SDK 中的 json_object_set_string 与 json_object_dotset_string
- javascript - 用于同步 Discord 频道和 Twitch 聊天的 JavaScript 机器人
- tumblr - 一直在编辑 Tumblr 主题,现在它在保存后提供非 HTTPS