我有一个执行搜索的功能。搜索可以通过几种不同的方式完成(通过查找ID或查询一些属性)。但是,我想限制传递哪些属性。我认为我可以做类似的事情:
interface Search {
_id?: string
people?: number
partyName?: string
otherField? string
}
function search(query: Search) {
myDbConnection.find(query).then(... // etc
}
问题是任何对象都符合这一点,query
可以包含额外的属性。例如,这可以通过:
search({otherField: "foo", aProtectedField: "bar"})
和aProtectedField
将传递给find
。
我想知道是否有一种打字方式来强制传递的属性。来自Rails世界的一些强参数。我知道我可以做pick
形式lodash或者甚至可以创建一个SearchObject
类并使用构造函数作为丢弃额外属性的方法,但我觉得有办法在我不知道的打字稿。
答案 0 :(得分:0)
您可以创建所需的所有属性,然后执行断言以传递属性的子集。
例如:
interface Search {
_id: string;
people: number;
partyName: string;
otherField: string;
}
function search(query: Search) {
// code here
}
search({ people: 2 } as Search); // ok
search({ otherField: "foo", aProtectedField: "bar" }); // error, good
search({ otherField: "foo", aProtectedField: "bar" } as Search); // error, good
答案 1 :(得分:0)
你在使用什么版本的Typescript?自从Typescript 1.6出现improved checking for object literals。
在TS 1.8上,当我尝试运行你的代码时,我得到了:
错误TS2345:类型'{otherField:string; aProtectedField:string; }'不能分配给'搜索'类型的参数。 对象文字只能指定已知属性,'搜索'类型中不存在'aProtectedField'。
这个和noImplicitAny应该抓住你担心的错误。
答案 2 :(得分:0)
我想限制可以传递的属性。[...]查询可以包含额外的属性。
我看待它的方式,这是有争议的。如果限制给定对象可能包含的属性,则根据定义,它仅限于该组属性,并且不能包含其规范不允许的其他属性。
由于您对any
类型几乎没有任何帮助,我的建议是通过为其他属性定义一个选项来解决这种类型安全的方法:
interface Search {
_id?: string;
people?: number;
partyName?: string;
additionalFields?: { [key: string]: any };
}
search({ people: 2 }); // ok
search({ _id: "jd", people: 2 }); // ok
search({ _id: "jd", additionalFields: { otherField: "foo" } }); // ok