当前位置: 首页 > 知识库问答 >
问题:

前端 - 求大佬,这样的情况typescript如何定义对象?

邓兴为
2023-08-13

已知有一个对象,key和value对应

{    a: { a1: 1 },    b: { b9: 1 },    c: { c5: 1 },    d: { d2: 1 },    ...}

怎么用ts来定义这样的数组?

[{    type: 'e',    value: { e1: 1 }}, {    type: 'c',    value: { c5: 1 }}]

共有2个答案

花品
2023-08-13

研究了一下,这个问题可以分为两个部分

  1. 如何约束转化函数的入参类型

利用 template type 很方便可以解决:

type Src<Ks extends string> = {    [K in Ks]: {        [P in `${K}${number}`]: number    }}const conv = <Ks extends string>(src: Src<Ks>) => {}
  1. 如何推导返回值类型:

我能想到的是 record 转 union 转 array,其中 UnionToArray 参考了网上的文章。

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (  k: infer I) => void    ? I    : nevertype UnionToOvlds<U> = UnionToIntersection<    U extends any ? (f: U) => void : never>type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : nevertype IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : truetype UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true    ? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]>    : [T, ...A]type Src<Ks extends string> = {    [K in Ks]: {        [P in `${K}${number}`]: number    }}const conv = <Ks extends string, T extends Src<Ks>>(src: T) => {    const dist: { type: string, value: { [K: string]: number } }[] = []    for (const k in src) {        dist.push({ type: k, value: src[k] })    }    return dist as UnionToArray<{        [K in keyof T]: {            type: K            value: T[K]        }    }[keyof T]>}const dist = conv(src)//    ^?//    const dist: [{//        type: "a";//        value: {//            a1: number;//        };//    }, {//        type: "b";//        value: {//            b9: number;//        };//    }, {//        type: "c";//        value: {//            c5: number;//        };//    }, {//        type: "d";//        value: {//            d2: number;//        };//    }]

遗憾的是这两个思路不能共存于一个函数(在我看来),你可以按需求选择入参约束或返回类型。

苏品
2023-08-13

一个并不完善的 type

type Obj = {  [props: string]: {    [props: string]: number;  };};type Pack<T extends Obj> = {  type: keyof T;  value: T[keyof T];}[];

测试使用

const obj = {  a: { a1: 1 },  b: { b9: 1 },  c: { c5: 1 },  d: { d2: 1 },};const goodVal: Pack<typeof obj> = [  {    type: "a",    value: { a1: 10 },  },  {    type: "c",    value: { c5: 1 },  },];const badVal: Pack<typeof obj> = [  {    type: "e",    value: { e1: 1 },  },  {    type: "f",    value: { f6: 1 },  },];

之所以说不完善,是因为没有限制 valuekey 必须包含 type 前缀:

const val: Pack<typeof obj> = [  {    type: "a",    // 应该为 "a1"    value: { b9: 1 },  },  {    type: "d",    // 应该为 ”d2“    value: { a1: 1 },  },];
 类似资料: