Closed
Description
openedon Apr 3, 2019
TypeScript Version: 3.4.0-dev.20190403
Code
function toHTML<T, K extends keyof T>(items: T[], key: T[K] extends T[] ? K : never) {
if (!items.length) return '';
// i[key] here is an error :(
const innerHTML = items.map(i => `<li>${i}${toHTML(i[key], key)}</li>`).join('\n');
return `<ul>\n${innerHTML}\n</ul>`;
}
class Item {
constructor(public name: string, public nodes: Item[]) { }
toString() { return this.name; }
}
const tree = [
new Item("Root", [
new Item("Node 1", [new Item("Subnode 1", [])]),
new Item("Node 2", [])
])
];
// This works correctly! Anything but 'nodes' (eg. 'name') is an error.
document.write(toHTML(tree, 'nodes'));
Idea: Take a list of type T
and a key K
into type T
that returns a T[]
and recursively walk the entire tree.
Expected behavior:
If I specify that a keyof T
must extend T[]
(or it becomes never
), I can use it as such.
Actual behavior:
It partially works, but indexing into the T
type with K
shows the error:
test.ts:4:56 - error TS2345: Argument of type 'T[T[K] extends T[] ? K : never]' is not assignable to parameter of type 'T[]'.
4 const innerHTML = items.map(i => `<li>${i}${toHTML(i[key], key)}</li>`).join('\n');
~~~~~~
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment