gpt4 book ai didi

javascript - 是否可以在 TypeScript 的嵌套结构中使用不同的类型参数?

转载 作者:行者123 更新时间:2023-11-30 11:08:30 28 4
gpt4 key购买 nike

一个简单的示例对应于这个问题“一个简单的通用类型和类型安全的 LinkedList,如数据结构”,其中每个下一个节点可以是不同的类型。比如本意是这样实现的:

     interface LinkedNode<T1> {
value: T1;
next: LinkedNode<T2> | null; // Typescript gives error for T2 here.
}

Use case:
interface IPair{
a:boolean;
b: number;
}
let LinkedNode1: LinkedNode<string> = {value: "string1", next: null};
let LinkedNode2: LinkedNode<number> = {value: 10, next: LinkedNode1};
let LinkedNode3: LinkedNode<IPair> = {value: {a:true, b: 2}, next: LinkedNode2};
let root: LinkedNode<boolean> = {value: true, next: LinkedNode3};

let x = root.next.value.a; // ultimately this is the desired effect: to be able to get access to other linked node's member variables without having to manually typecast.

因此,问题是:“对于上面的 LinkedNode<T1> 接口(interface),将 <T2> 替换为 <any> 可以编译,但会丢失类型信息。是否可以在不使用 <any> 的情况下实现上述预期效果<T2> ? 如果不是,还有什么选择?”

最佳答案

如果我没理解错的话,你真的想要一个 tuple元组中的每个元素都下降一级到树中的类型。或者至少这是对我来说唯一有意义的事情,因为您必须根据所有后代的类型来定义根节点的类型。

给定几个tuple-related features added in TypeScript 3.0 ,您可以执行以下操作:

// get the first element of a tuple; Head<[1,2,3]> is 1
type Head<L extends any[]> =
((...l: L) => void) extends ((h: infer H, ...t: infer T) => void) ? H : never;

// get the tuple with the first element removed; Tail<[1,2,3]> is [2,3]
type Tail<L extends any[]> =
((...l: L) => void) extends ((h: infer H, ...t: infer T) => void) ? T : never;

// represent LinkedNode in the following nested way
interface LinkedNode<T extends any[]> {
value: Head<T>;
next: LinkedNode<Tail<T>> | null;
}

当您到达元组末尾时,会发生一些有趣的事情,(LinkedNode<[]>LinkedNode<never> 是有趣的类型)但是 | null隐藏得很好。

让我们试试看:

const node: LinkedNode<[string, number, boolean]> = {
value: "a",
next: {
value: 1,
next: {
value: true,
next: null
}
}
};

let LinkedNode1: LinkedNode<[string]> = { value: "string1", next: null };
let LinkedNode2: LinkedNode<[number, string]> = { value: 10, next: LinkedNode1 };
let LinkedNode3: LinkedNode<[IPair, number, string]> = { value: { a: true, b: 2 }, next: LinkedNode2 };
let root: LinkedNode<[boolean, IPair, number, string]> = { value: true, next: LinkedNode3 };

我觉得不错。


在 TS3.0 之前,您可以获得带有嵌套泛型的东西,这可能更直接:

interface LinkedNode<T, N extends null | LinkedNode<any, any>=null> {
value: T;
next: N;
}

const node: LinkedNode<string, LinkedNode<number, LinkedNode<boolean>>> = {
value: "a",
next: {
value: 1,
next: {
value: true,
next: null
}
}
};

let LinkedNode1: LinkedNode<string> = {value: "string1", next: null};
let LinkedNode2: LinkedNode<number, typeof LinkedNode1> = {value: 10, next: LinkedNode1};
let LinkedNode3: LinkedNode<IPair, typeof LinkedNode2> = {value: {a:true, b: 2}, next: LinkedNode2};
let root: LinkedNode<boolean, typeof LinkedNode3> = {value: true, next: LinkedNode3};

看起来也不错。其中一个有帮助吗?

关于javascript - 是否可以在 TypeScript 的嵌套结构中使用不同的类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54716156/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com