TS 识别变量中的元组tuple,让代码提示更准确

324 阅读1分钟

目标需求

键入apis.logIn[2]时,有正确的代码提示

const apis = {
    logIn: ["/login", "登录", {
        userName: "",
        password: ""
    }],
    list: ["/list", "获取商品列表", { id: 0 }],
    time: ["/time", "获取最新时间"],
};

方式1[预先定义api类型]

可以把api识别为tuple,但是params的提示依然不准确

type Api = [url: string, name: string, params?: any]
const api: Api = ["/login", "登录", {
    userName: "",
    password: ""
}]

方式2[as const]

有些需求不满足,as const意味着readonly

(apis as const).logIn[2]

方式3☆[根据变量apis生成类型]

type Tuple2Union<T extends unknown[], Res = never> =
    T extends [infer T1, ...infer TR] ?
    TR["length"] extends 0 ?
    T1 extends never ? Res : Res | T1
    : Tuple2Union<TR, Res | T1>
    : Res;

type Union2Tuple<Union, Tup extends unknown[]> =
    Tup extends [...infer Cache, infer Discard]
    ? [...Cache, Exclude<Union, Tuple2Union<Cache>>] : never;

type RecordStrTup<
    T extends Record<string, unknown[]>,
    Tup extends unknown[]> = {
        [Key in keyof T]: Union2Tuple<T[Key][0], Tup>;
    };
//只支持最后一个元素是未知类型
type Api = [url: string, desc: number, params: unknown];

type Apis = RecordStrTup<typeof apis, Api>;

(apis as Apis).logIn[2]

帖子推荐

接近天花板的TS类型体操,看懂你就能玩转TS了

Typescript 骚操作大全

TypeScript体操运动员进阶指南

[题库]TypeScript 类型体操姿势合集