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时,该链表结束。

相关推荐
JustHappy44 分钟前
古法编程秘籍(七):互联网到底是什么?把两台电脑怎么说话搞懂就够了
前端·后端·网络协议
老毛肚1 小时前
jeecg-boot-base-core 02 day
javascript·python
snow@li1 小时前
SEO-文章标题:写文章时候,分类+主标题+大纲+解释 作为标题 / 不点进去也知道全文覆盖什么 / 标题即架构
前端
kyriewen2 小时前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
小和尚同志2 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
老马识途2.02 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕3 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@3 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#4 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar4 小时前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github