Scala understreck i TypeScript - implementerat men omöjligt att skriva
Ganska säker på att det är omöjligt, har varit ett sidoprojekt för mig i 2 år nu att implementera Scalas understreck i Typescript men kan inte riktigt nå dit, detta är implementationen och effekten.
Det enda jag bryr mig om typen av är "Understreck" allt annat kan du bara ignorera.
const buildUnderscore = (f: any) => (path: any[]): any => new Proxy(f, handler(path));
const handler = (path: any[]) => ({
get: function(obj: any, prop: any, value: any) {
return buildUnderscore((a: any) => getAtPath(a, path.concat(prop)))(path.concat(prop));
}
})
/* takes object A and key path ["a", "b", "c"] -> returns A["a"]["b"]["c"] */
const getAtPath = (obj: any, [head, ...tail]: string[]): any => {
if(head === undefined) return obj;
return getAtPath(obj[head], tail);
}
/* Ignore all implementation above i don't care if its typed this is the only thing i care that's typed */
const _: Underscore = buildUnderscore((a: any) => a)([]);
// ConvertKeysToFunctions<GetArgs<Array<T>["map"]>[0]> is what i need
// but there's no way to infer T
// where GetArgs gets the first argument of Array["map"]
// and ConvertKeysToFunctions converts that types keys to function types
type Underscore = <T>(a: T) => T
const data = [
{
child: {
name: "bob",
children: ["sue", "john"]
}
},
{
child: {
name: "catness",
children: ["rue", "hew"]
}
},
]
console.log(data.map(_)) // converts to data.map((a) => a)
console.log(data.map(_.child.children[0]))// converts to: data.map((a) => a["child"]["children"][0])
console.log(data.map(_.child)) // converts to data.map((a) => a["child"])
Svar #1
Tyvärr saknar TypeScript för närvarande möjligheten att referera till ett dynamiskt namn på en egenskap i ett objekt, vilket gör proxies svåra att använda/typa med TypeScript.
Förmodligen är det närmaste du kan ha att bara använda en lambda:
_ => _.foo.bar
Om någon av egenskaperna på vägen är valfri skulle du behöva använda mörk typmagi precis som jag gjorde i mitt bibliotek för liknande syfte. Var dock försiktig, att använda något sådant kan dramatiskt sakta ner kompilationsprocessen.
