2017-04-23 9 views
0

Ich muss den Typ als Ergebnis der gleichen wie das Ergebnis2 erhalten. Ist es möglich, es irgendwie zu lösen, indem Sie die Funktion ändern getNestedProperty?Kann ich den richtigen Typ mit einer großen Verschachtelung bekommen

interface ILevel3 { 
    level3:() => void; 
} 

interface ILevel2 { 
    level2: ILevel3; 
} 
interface ILevel1 { 
    level1: ILevel2; 
} 

const bigNestedObject: ILevel1 = { 
    level1: { 
    level2: { 
     level3:() => {} 
    } 
    } 
}; 

const result = getNestedProperty(bigNestedObject)('level1.level2.level3'); 
result(); // error type object 

const result2 = bigNestedObject.level1.level2.level3; 
result2(); // it's ok type =() => void 

const getNestedProperty = (root: object) => (propertyString: string): object => { 
    return propertyString 
      .split('.') 
      .reduce(<R, KPath extends keyof R>(acc: R, current: KPath): R[KPath] => acc[current], root); 
} 

Kann ich in Ergebnis gültig type =() => außer Kraft gesetzt?

Antwort

1

Ich denke, Sie können versuchen, Ihren Code neu zu ordnen. Beachten Sie, dass const getNestedPropertygetNestedProperty eine Blockbereichsvariable darstellt. Also bevor Sie es verwenden, müssen Sie die Variable deklarieren.

Beachten Sie auch, dass der letzte Rückgabetyp von der Funktion, die mit der Funktion höherer Ordnung ausgeführt wird, vom Typ object ist, dem die Signatur fehlt. Um das zurückgegebene Funktionsobjekt aufzurufen, kann es daher nützlich sein, es asFunction zu werfen.

Im Folgenden finden Sie die komplette Beispiel:

//omitting interfaces for brevity 

const bigNestedObject: ILevel1 = { 
    level1: { 
    level2: { 
     level3:() => { 
     console.log("Hello World"); 
     } 
    } 
    } 
}; 

function core<R, KPath extends keyof R>(acc: R, current: KPath): any { 
    return acc[current]; 
} 

const getNestedProperty = (root: object) => (propertyString: string): object => { 

    //the core function can also be defined here inside getNestedProperty 

    return propertyString 
      .split('.') 
      //.reduce(<R, KPath extends keyof R>(acc: R, current: KPath): R[KPath] => acc[current], root); 

      //the old commented code should also work, 
      //but note this makes the code easier to read. 
      .reduce(core, root); 
} 

const result = getNestedProperty(bigNestedObject)('level1.level2.level3'); 
console.log(result); // [Function: level3] 

const result2 = bigNestedObject.level1.level2.level3; 
console.log(result2); // [Function: level3] 

(result as Function)(); //Hello World 

Hoffnung, das hilft.


Update: Der obige Code geändert und kommentierte ass pro Vorschlag von Aluan Haddad unten. Beachten Sie, dass die neue Funktion core (besseren Namen finden) hinzugefügt wird, da sie den Code verständlicher macht. Der alte Code sollte, wie gesagt, ebenfalls funktionieren.

+0

+1. Kann ich vorschlagen, dass Sie die reduce-Funktion in eine verschachtelte Funktion oder eine "const" -Deklaration zur besseren Lesbarkeit extrahieren? –

+0

@AluanHaddad Vielen Dank für Ihren Vorschlag. Es wird tatsächlich die Lesbarkeit verbessern. Aber der Code stammt aus dem OP, und ich möchte ihn als seinen aktuellen Zustand belassen, da das das Problem nicht verursacht, und ich überprüfe den Code nicht, sondern biete eine Lösung für das besagte Problem. Ich hoffe du verstehst. –

+0

Ich nehme an, aber es tut nicht weh, ein gutes Beispiel zu geben. –

Verwandte Themen