我有一个方法,只要它的所有字段都是字符串或数字,它就可以接受任何对象
我做了这个,非常适合鸭子打字
static interpolateParams(
route: string,
params: {[key: string] : string | number}) : string {
const parts = route
.split("/")
.map(part => {
const match = part.match(/:([a-zA-Z09]*)\??/);
if (match) {
if (!params[match[1]]) {
console.error("route argument was not provided", route, match[1]);
return part;
}
return params[match[1]];
}
else {
return part;
}
})
return "/" + parts.slice(1).join("/");
}
并致电
interpolateParams("/api/:method/:value", {method: "abc", value: 10});
现在,我想让interpolateParams
接受路由params
的任何接口。
interpolateParams<IABCParams>("/api/:method/:value", {method: "abc", value: 10});
问题在于,对于所有字符串或数字字段,它仍应匹配约束条件
是否可以在给定接口的所有字段上将通用约束指定为特定类型?
我尝试过
static interpolateParams<T extends {[key: string] : string | number}>(
route: string,
params: T) : string {
显然知道了
类型'IABCParams'不满足约束'{[键:字符串]:字符串|数; }'。
“ IABCParams”类型中缺少索引签名。
谢谢
答案 0 :(得分:3)
D:\avsts140\_work\2\.tmp\node_modules\.bin;
的约束可以引用T
(有一些限制),因此您可以使用映射类型生成与T
具有相同字段的约束:>
T
请注意,使用循环类型参数约束的欺骗有时可能会导致问题,尽管这种情况很可能会解决。
答案 1 :(得分:1)
这是最终版本,感谢马特的提示
static interpolateParams(
route: string,
params: {[key: string] : string | number}) : string {
const parts = route
.split("/")
.map(part => {
const match = part.match(/:([a-zA-Z09]*)\??/);
if (match) {
if (!params[match[1]]) {
if (part.endsWith("?")) {
return null;
}
console.error("route argument was not provided", route, match[1]);
return part;
}
return params[match[1]];
}
else {
return part;
}
}).filter(p => p && p != "");
return "/" + parts.join("/");
}
static formatRoute<T extends {[P in keyof T] : string | number}>(
route: string,
params: T
) : string {
return interpolateParams(route, params);
}
答案 2 :(得分:0)
如果您想interpolateParams("/api/:method/:value", {method: "abc", value: 10});
进行类型检查,则不能。这是因为您无法推断出有关"/api/:method/:value"
的任何信息以给您method,value
签名。
编写带有method
和value
的函数,并使用它们为配置和使用提供动力。
例如这是我与takeme一起使用的策略。
// Define
export const links = {
profile: (id: string) => `/profile/${id}`
}
// Use in Configure
links.profile(':profileId')
// Use in Navigate / a tags
links.profile(user.id)