请教在Typescript中如何使用递归函数返回正确的数据类型?

作者站长头像
站长
· 阅读数 10

TS演示:https://tsplay.dev/mLO04N , 问题:当我将reduce中返回对象的children注释去掉,返回的类型就变成any了,请问正确姿势应该是?

interface LocationItem {
    code: string;
    name: string;
    cities?: Record<string, LocationItem>;
    districts?: Record<string, string>;
}

interface Option {
    value: string | number;
    label: string;
    children?: Option[];
}

const objectEntries = <T extends object, K = keyof T>(obj: T) => Object.entries(obj) as Array<[K, T[keyof T]]>;

const transform = (data: Record<string, LocationItem | string>|undefined = {}) =>
    objectEntries(data).reduce((buf, [key, value]) => {
        if (typeof value === "string") {
            return [...buf, { label: value, value: key }];
        }

        const { code, name, cities, districts } = value;
        const _cities = transform(cities);
        const _districts = transform(districts);

        const children = _cities.length ? _cities : _districts.length ? _districts : undefined;
        return [
            ...buf,
            {
                label: name,
                value: code,
                // children,
            },
        ];
    }, [] as Option[]);

我把提取的值像这样复制给一个对象,获取的类型是对的,但是如果把这个对象作为返回数据类型就不对了

请教在Typescript中如何使用递归函数返回正确的数据类型?

请不要试图类似用下面断言的方式来解决,我试图通过正确的姿势获取数据类型:

const _cities = transform(cities) as Options[];
const _districts = transform(districts) as Options[];
回复
1个回答
avatar
test
2024-06-20
const transform = (data: Record<string, LocationItem | string> = {}) =>
    Object.entries(data).reduce<Option[]>((buf, [key, value]) => {
        if (typeof value === 'string') buf.push({ label: value, value: key })
        else {
            const { code, name, cities, districts } = value
            const _cities = transform(cities)
            const _districts = transform(districts)

            const children = _cities.length
                ? _cities
                : _districts.length
                ? _districts
                : undefined
            buf.push({ label: name, value: code, children: children })
        }
        return buf
    }, [])
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容