typescript递归数据结构的定义和处理

typescript是一种类型强约束的语言,一般来讲定义类型时都要明确指定类型的数据结构。而如果数据结构中涉及到不知道几层嵌套的递归时,就会有一些麻烦。

https://stackoverflow.com/questions/51657815/recursive-array-type-typescript

有一个回答说明了typescript中涉及到递归时的类型定义。

要点在于:要在类型内部增加自身的类型。

TypeScript 复制代码
// 当你需要不确定末端节点的类型时,可以先定义一个Atom类型作为联合类型
type Atom = string | boolean | number
type NestedArray = Array<NestedArray | Atom>;
interface NestedArray extends Array<NestedArray | Atom> {}
// 当你确定末端节点的类型时,无需定义Atom类型,直接使用末端的类型即可
type RecursiveVector = Array<RecursiveVector | number>;
interface RecursiveVector extends Array<RecursiveVector | number> {}

如果需要更强的适应性,那就得使用模板

TypeScript 复制代码
export interface NestedArray<T> extends Array<NestedArray<T> | T> {}

每次调用的时候,指定T的类型

在针对递归类型编写递归代码时,需要对当前递归的类型做判断:是否末端节点。如果是末端节点,则进行直接计算;如果不是末端节点,那么进入下一层递归。

比如说下面的代码用于求某两个递归数据结构中间比例的插值数值

TypeScript 复制代码
function ArrayLinearInterpolation(startArray: RecursiveVector, endArray: RecursiveVector, param: number) {
    function tmpFun(startArray: RecursiveVector, endArray: RecursiveVector): RecursiveVector {
        if (!isArray(startArray) || !isArray(endArray)) {
            throw TypeError("startArray or endArray is not Array");
        }
        if (startArray.length != endArray.length) {
            throw TypeError("the dimension of startArray and endArray don't match");
        }
        let res: RecursiveVector = [];
        for (let j = 0; j < startArray.length; j++) {
            if (isNumber(startArray[j]) && isNumber(endArray[j])) {
                res.push((startArray[j] as number) + param * ((endArray[j] as number) - (startArray[j] as number)));
                continue;
            } else {
                res.push(tmpFun(startArray[j] as RecursiveVector, endArray[j] as RecursiveVector));
            }
        }
        return res;
    }
    return tmpFun(startArray, endArray);
}

返回值res必须定义为递归数据结构。在对递归数据进行节点末端判断后,再根据"是否末端"进行分别处理。

当针对末端调用递归函数进行处理时,必须用as指定末端数据类型,否则typescript在类型识别时会判断错误。当针对非末端调用递归函数进行处理时,也必须用as指定非末端的数据类型,否则typescript在类型识别时也会判断错误。

如果末端数据类型不是语言自带的数据类型,而是用户自定义的复杂类型,可以按照下面这个帖子的说明处理。

typescript递归遍历_ts 递归-CSDN博客

本质上来讲,就是在递归数据结构定义中,把子数据的类型定义为递归数据类型自身。最简单的递归数据是只包含自身,复杂的就要包含一些其他的数据。

这个有点类似于C++的链表。在C++中,某个链表数据类型中会有一个子数据是指针,该指针指向下一个同样的数据类型,当该指针为nullprt时,该链表结束。

相关推荐
AlienZHOU2 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc5 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师6 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen7 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒7 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow7 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林8187 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang800787 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明7 小时前
第 6 章 组件进阶
前端·vue.js
江华森8 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端