Say I have the type type Atom = string | boolean | number
type Atom = string | boolean | number
type Atom = string | boolean | number
. I want to define a type of array like:
NestedArray = Atom | [a_0, a_1, ... , a_n]
NestedArray = Atom | [a_0, a_1, ... , a_n]
where each a_i
is an Atom
, or a NestedArray
.
Can this be achieved in Typescript?
Type aliases can't reference themselves, so this naïve approach will fail:
type NestedArray = Atom | Array<NestedArray | Atom> //Type alias 'NestedArray' circularly references itself.
Interfaces can however reference themselves:
interface NestedArray extends Array<NestedArray | Atom> {
}
And we can define an extra union at the top level to handle the root case:
type Atom = string | boolean | number
interface NestedArray extends Array<NestedArray | Atom> {
}
type AtomOrArray = Atom | NestedArray;
//Usage
let foo: AtomOrArray = [
"",
1,
[1, 2, ""]
]
let bar: AtomOrArray = ""
Now typescript allow type circularly references itself, such like this:
type RArray = (string | RArray)[];
And if you want to define a generic type in recursive function, can use interface ...<T> extends (T|...<T>)[]
interface RA<T> extends Array<T | RA<T>> { }
For example, create a function to get sum recursivily
function sum(arr: RA<number>) {
let res = 0;
arr.forEach((n) => {
if (Array.isArray(n)) {
res += sum(n);
} else {
res += n;
}
});
return res;
}
console.log(sum([1, 2, 3, [4, [5]], [[6]]]))
// output: 21
But this way has some disadvantage, compiler can't know the specific type of n
arr.forEach((n) => {
if (Array.isArray(n)) { // typeof n: `number | RA<number>`
res += sum(n);
} else {
res += n;
}
});
Based on this answer
Since typescript 3.7 you can create a general recoursive type:
type Tree<T> = T | Array<Tree<T>>
And then use it like this:
let stuff: Tree<string | boolean | number> = ["lala", [1, "stuffy"], 3, false];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.