Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在对象上设置值的泛型类型,而不指定键类型_Javascript_Typescript_Typescript Typings - Fatal编程技术网

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
的要点是,对象本身就是真理的来源,我不需要管理两个地方的端点列表。如果我不必这样包装,那就更好了,但它可以工作!为了可读性,我会看看在很多地方使用这个技巧是否值得,但我肯定会在一些实用程序代码中这样做。谢谢如果我不用做这个包裹会更好,但它很有效!为了可读性,我会看看在很多地方使用这个技巧是否值得,但我肯定会在一些实用程序代码中这样做。谢谢