Javascript 在对象上设置值的泛型类型,而不指定键类型
我的数据结构如下:Javascript 在对象上设置值的泛型类型,而不指定键类型,javascript,typescript,typescript-typings,Javascript,Typescript,Typescript Typings,我的数据结构如下: const endpoints = { async Login: (params) => { ... } async Register: (params) => { ... } } interface EndpointMap { [endpointName: string]: ( params: Record<string, any> ) => Promise<any>; } 现在我想指定这个对象中的每个项
const endpoints = {
async Login: (params) => { ... }
async Register: (params) => { ... }
}
interface EndpointMap {
[endpointName: string]: (
params: Record<string, any>
) => Promise<any>;
}
现在我想指定这个对象中的每个项都必须接受params对象并返回一个承诺
我可以这样做:
const endpoints = {
async Login: (params) => { ... }
async Register: (params) => { ... }
}
interface EndpointMap {
[endpointName: string]: (
params: Record<string, any>
) => Promise<any>;
}
接口端点映射{
[端点名称:字符串]:(
参数:记录
)=>承诺;
}
这很有效。但这也有不利的一面
如果我在其他地方这样做,例如endpoint:keyof-typeof-endpoints
,结果只会是string
。如果我删除EndpointMap
接口,我将得到endpoint
对象上所有键的字符串并集。好多了
有没有一种方法可以同时兼顾两个世界
谢谢 实现这一点的一种方法是不将键作为类型字符串提供,而是在类型
端点映射中定义键:
type EndpointMap = {
[key in 'Login' | 'Register']: (
params: any
) => Promise<any>
}
const endpoints: EndpointMap = {
Login: (params) => { ... },
Register: (params) => {... }
}
// Valid
const oneKey: keyof typeof endpoints = 'Login'
// Type '"Random"' is not assignable to type '"Login" | "Register"'
const otherKey: keyof typeof endpoints = 'Random'
类型端点映射={
[输入“登录”|“注册”]:(
有吗
)=>承诺
}
常量终结点:终结点映射={
登录:(参数)=>{…},
寄存器:(参数)=>{…}
}
//有效的
const oneKey:keyof typeof endpoints='Login'
//类型“Random”不可分配给类型“Login”|“Register”'
const otherKey:keyof typeof endpoints='Random'
实现这一点的一种方法是,不要将键作为类型字符串提供,而是在类型端点映射中定义键:
type EndpointMap = {
[key in 'Login' | 'Register']: (
params: any
) => Promise<any>
}
const endpoints: EndpointMap = {
Login: (params) => { ... },
Register: (params) => {... }
}
// Valid
const oneKey: keyof typeof endpoints = 'Login'
// Type '"Random"' is not assignable to type '"Login" | "Register"'
const otherKey: keyof typeof endpoints = 'Random'
类型端点映射={
[输入“登录”|“注册”]:(
有吗
)=>承诺
}
常量终结点:终结点映射={
登录:(参数)=>{…},
寄存器:(参数)=>{…}
}
//有效的
const oneKey:keyof typeof endpoints='Login'
//类型“Random”不可分配给类型“Login”|“Register”'
const otherKey:keyof typeof endpoints='Random'
您可以通过使用identity函数创建端点来实现这一点:
interface EndpointMap {
[endpointName: string]: (
params: Record<string, any>
) => Promise<any>;
}
const createEndpoints = <TMap extends EndpointMap>(map: TMap) => map;
const endpoints = createEndpoints({
login: async (params) => ({}),
register: async (params) => ({})
});
/*
type of 'endpoints' variable is:
{
login: (params: Record<string, any>) => Promise<{}>;
register: (params: Record<string, any>) => Promise<{}>;
}
*/
您可以通过使用identity函数创建端点来实现这一点:
interface EndpointMap {
[endpointName: string]: (
params: Record<string, any>
) => Promise<any>;
}
const createEndpoints = <TMap extends EndpointMap>(map: TMap) => map;
const endpoints = createEndpoints({
login: async (params) => ({}),
register: async (params) => ({})
});
/*
type of 'endpoints' variable is:
{
login: (params: Record<string, any>) => Promise<{}>;
register: (params: Record<string, any>) => Promise<{}>;
}
*/
但这也有不利的一面,是的。它也将接受对象值{foo:(params)=>{}
。如果您知道密钥,则应该指定它们。这甚至有助于TS为你提供智能感知。但这也有一个缺点,是的。它也将接受对象值{foo:(params)=>{}
。如果您知道密钥,则应该指定它们。这甚至有助于TS为您提供智能感知。输入
很好,但此时我可以编写字符串联合。在这里重用它,在其他地方也使用它,我就不必使用keyof-typeof
。对我来说,keyof-typeof
的要点是对象本身就是真理的来源,我不需要管理两个地方的端点列表。key-in
很好,但在这一点上,我可以编写字符串并集。在这里重用它,在其他地方也使用它,我就不必使用keyof-typeof
。对我来说,keyof-typeof
的要点是,对象本身就是真理的来源,我不需要管理两个地方的端点列表。如果我不必这样包装,那就更好了,但它可以工作!为了可读性,我会看看在很多地方使用这个技巧是否值得,但我肯定会在一些实用程序代码中这样做。谢谢如果我不用做这个包裹会更好,但它很有效!为了可读性,我会看看在很多地方使用这个技巧是否值得,但我肯定会在一些实用程序代码中这样做。谢谢