2016-09-10 12 views
0

versuchen SchlüsselKonvertieren von Objektschlüssel

import { Url, parse } from "url"; 
export class HalJson { 
    _links: Links; 
} 

export class HalLinks implements Links { 
    toUrl(rel: string): Url { 
     let link = <Link> this[rel]; 
     return parse(link.href); 
    } 
    [text: string]: Link; 
} 

export interface Links { 
    [text: string]: Link; 
    toUrl(rel : string) : Url; 
} 

export interface Link { 
    href: string; 
} 

aber ich bekomme diese Fehlermeldung

[default] C:\Users\xeno\IdeaProjects\rpf-ui\src\util\Hal.ts:7:5 
    Property 'toUrl' of type '(rel: string) => Url' is not assignable to string index type 'Link'. 
[default] C:\Users\xeno\IdeaProjects\rpf-ui\src\util\Hal.ts:16:5 
    Property 'toUrl' of type '(rel: string) => Url' is not assignable to string index type 'Link'. 

hier ist der Instanziierung-Code, der funktioniert (ohne die toUrl Code)

client.fetch('').then(response => { 
     return response.json(); 
    }).then(json => { 
     let hal: HalJson = Object.assign(new HalJson(), json); 
     hal._links = Object.assign(new HalLinks(), hal._links); 
     log.debug("json", hal); 

ich konvertieren Ich versuche herauszufinden, wie ich ein Url Objekt von meinemzurückbekommen kannNutzlast

(alternativ, wenn jemand irgendwelche Typoskript Definitionen Bibliotheken kennt, die hal json Links nehmen würde und es streng typisierte machen, fühlen Sie sich frei in den Kommentaren zu erwähnen) können

+0

Wie erstellen Sie eine Instanz von 'HalLinks'? –

+0

@NitzanTomer hinzugefügt, nicht, dass es so hilfreich sein wird – xenoterracide

+0

Ich glaube nicht, was Sie tun, ist erlaubt. Der Indexer ist die bevorzugte Übereinstimmung für * all * -Eigenschaften, daher versucht der Compiler, HalLinks # toUrl als nur einen anderen String-Index zu prüfen. Wenn Sie versuchen, Ihrer Schnittstelle eine Eigenschaft hinzuzufügen, die nicht vom Typ "Link" (oder einem Subtyp) ist, erhalten Sie einen Kompilierungsfehler. Könnte ein Compiler-Fehler sein, dass dies bei Methoden nicht passiert. –

Antwort

0

Der Compiler beschwert sich, weil eine Instanz von Links verwendet werden wie folgt aus:

let a = links["toUrl"]("rel"); 

was ist dann die Art von a? Ist es ein Link oder Url?
Sie tun können:

interface Links { 
    [text: string]: Link | Url; 
    toUrl(rel: string): Url; 
} 

class HalLinks implements Links { 
    toUrl(rel: string): Url { 
     let link = <Link> this[rel]; 
     return parse(link.href); 
    } 
    [text: string]: Link | Url; 
} 

Aber dann werden Sie brauchen, um alles zu werfen, die Sie von HalLinks abrufen:

let a1 = links["rel"] as Link; 
let a2 = links["rel"] as Url; // no error, which isn't good. 

schlage ich etwas, das mehr Code erfordert, aber ich denke, dass es einfacher sein wird, mit zu arbeiten:

interface Links { 
    [text: string]: Link; 
} 

class HalLink { 
    constructor(private link: Link) {} 

    get href(): string { 
     return this.link.href; 
    } 

    get url(): Url { 
     return parse(this.link.href); 
    } 
} 

class HalLinks { 
    private links: { [rel: string]: HalLink }; 

    constructor(links: Links) { 
     this.links = {}; 

     for (let key in links) { 
      this.links[key] = new HalLink(links[key]); 
     } 
    } 

    get(rel: string): HalLink { 
     return this.links[rel]; 
    } 

    url(rel: string): Url { 
     return this.links[rel].url; 
    } 
} 

let links: HalLinks; 

let link1 = links.get("rel1"); 
let href1 = link1.href; 
let url1 = link1.url; 

let url2 = links.url("rel2"); 
+0

nicht ganz so anders als der alternative Ansatz ich kam mit der Export-Klasse HalJson { Konstruktor (JSON: any) { lassen Hal: HalJson = Object.assign (diese, JSON); hal._links = Object.assign (new HalLinks(), hal._links); Object.keys (hal._links) .forEach (Schlüssel => { hal._links [Schlüssel] = Object.assign (new HalLink(), hal._links [key]) }); } 'und dann die' toUrl' als Getter auf den 'Link' setzen – xenoterracide

+0

Es ist sehr unterschiedlich. Aus diesem Grund sind Sie in meiner Lösung nicht mit dem Fehler konfrontiert, den Ihre Lösung verursacht. –

+0

Welchen Fehler würde ich in der Lösung im Kommentar erfahren? – xenoterracide