【问题标题】:How to narrow typescript array of string literal/string enum values如何缩小字符串文字/字符串枚举值的打字稿数组
【发布时间】:2019-03-24 21:31:08
【问题描述】:

假设我有一个看起来像这样的界面:

type RequestProps = "a" | "b" | "c"
interface Request {
   props: RequestProps[];
}

以及一些接受请求并返回响应对象的代码:

declare function sendRequest(r: Request);

我想缩小r.props 的范围,以便我可以返回带有与请求的道具相对应的键的响应。也就是说,如果请求是由这样的用户发出的:

const request = {
  props: ["a", "c"]
}
let response = sendRequest(request);

response 将自动完成 response.aresponse.c 作为字符串值。类似于

type Response<T extends RequestProps[]> = { [key in T[number]]: string; }

我不希望请求创建者必须指示字符串文字 ("a" as "a") 或元组 (["a", "c"] as ["a", "c"]),我希望 sendRequest 能够根据上下文推断或提示或保护某种方式允许将类型缩小到数组包含的实际文字值,无论多么冗长(如果必须,我将缩小每个排列)。这可能吗?字符串枚举似乎与字符串文字有相同的问题。谢谢!

【问题讨论】:

    标签: typescript


    【解决方案1】:

    假设您定义:

    declare function sendRequest<T extends RequestProps[]>(r: {props: T}): Response<T>;
    

    正如我认为的那样。然后以下工作:

    let response = sendRequest({
      props: ["a", "c"]
    });
    

    如果您不想立即发送请求,则必须以某种方式阻止 props 元素扩大。一个众所周知的技巧是通过应用适当上下文类型的函数运行请求:

    declare function asRequest<T extends RequestProps[]>(r: {props: T}): {props: T};
    let request = asRequest({
      props: ["a", "c"]
    });
    

    如果你真的希望能够将请求写成对象文字并将其保存在变量中而不使用辅助函数,你可以使用一堆单成员枚举,尽管这对我来说似乎不合理:

    enum AA { A = "a" }
    enum BB { B = "b" }
    enum CC { C = "c" }
    const A = AA.A, B = BB.B, C = CC.C;
    type RequestProps2 = AA | BB | CC;
    interface Request2 {
       props: RequestProps2[];
    }
    
    type Response2<T extends RequestProps2[]> = { [key in T[number]]: string; }
    declare function sendRequest2<T extends RequestProps2[]>(r: {props: T}): Response2<T>;
    
    let request2 = {
        props: [A, C]
    };
    let response2 = sendRequest2(request2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      • 2018-10-23
      • 1970-01-01
      • 2018-11-09
      • 2020-07-11
      • 1970-01-01
      • 2019-10-30
      相关资源
      最近更新 更多