[英]Typescript, How to write a typed flatten method for array
我正在嘗試在打字稿中編寫類似於https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat 的內容
但是,我希望能夠展平任意深度的嵌套列表; 而且我想將所有非數組元素限制為單一類型。
就像是:
interface NestedList<T> extends Array<T | NestedList<T>> {}
到目前為止我已經得到了這個:
export const flat = <T>(ls: NestedList<T>): T[] => {
const reducer = (acc: T[], it: T | NestedList<T>): T[] => acc.concat(
Array.isArray(it) ? it.reduce(reducer, []) : it
);
return ls.reduce(reducer, []);
};
但是,類型推斷似乎不起作用
it('works with type inference', () => {
interface Foo<T> { v: T; }
const data: { [_: string]: { [_: string]: Foo<number> } } = {
bar: { x: { v: 1 } },
moo: { y: { v: 2 }, z: { v: 3 } }
};
const nested: Foo<number>[][] = Object.values(data).map(val => Object.values(val));
const list2: Foo<number>[] = flat(nested);
expect(list2).toEqual([{ v: 1 }, { v: 2 }, { v: 3 }]);
});
它在這一行收到類型錯誤:
const list2: Foo<number>[] = flat(nested);
錯誤:
Type '(Foo<number>[] | ConcatArray<Foo<number>[]>)[]' is not assignable to type 'Foo<number>[]'.
Type 'Foo<number>[] | ConcatArray<Foo<number>[]>' is not assignable to type 'Foo<number>'.
Property 'v' is missing in type 'Foo<number>[]' but required in type 'Foo<number>'
我在這里缺少什么? 任何幫助表示贊賞。
我偶然發現了和你一樣的問題。 這是我想出的解決方案:
function flat<U>(arr: U[][]): U[] {
if ((arr as unknown as U[]).every((val) => !Array.isArray(val))) {
return (arr as unknown as U[]).slice();
}
return arr
.reduce((acc, val) => acc
.concat(Array.isArray(val) ? flat((val as unknown as U[][])) : val), []);
}
console.log(flat([[1,2],[[[3]]],4])
希望對你有幫助:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.