Wir haben bereits gute Antworten, aber ich denke, dass wir näher kommen können, was Sie in erster Linie wollte:
Sie können so etwas wie dies versuchen:
interface Document {
[index: number]: number | string | Document;
}
// compiles
const doc1: Document = [1, "one", [2, "two", [3, "three"]]];
// fails with "Index signatures are incompatible" which probably is what you want
const doc2: Document = [1, "one", [2, "two", { "three": 3 }]];
Im Vergleich zu NPE Antwort, Sie Brauchen keine Wrapper-Objekte um Strings und Zahlen.
Wenn Sie eine einzelne Nummer oder Zeichenfolge wollen ein gültiges Dokument sein (das ist nicht das, was Sie gefragt, aber was NPE Antwort impliziert), können Sie dies versuchen:
type ScalarDocument = number | string;
interface DocumentArray {
[index: number]: ScalarDocument | DocumentArray;
}
type Document = ScalarDocument | DocumentArray;
const doc1: Document = 1;
const doc2: Document = "one";
const doc3: Document = [ doc1, doc2 ];
Update:
Die Verwendung einer Schnittstelle mit Indexsignatur anstelle eines Arrays hat den Nachteil, dass Informationen vom Typ verloren gehen. Typescript lässt Sie Array-Methoden wie find, map oder forEach nicht aufrufen. Beispiel:
type ScalarDocument = number | string;
interface DocumentArray {
[index: number]: ScalarDocument | DocumentArray;
}
type Document = ScalarDocument | DocumentArray;
const doc1: Document = 1;
const doc2: Document = "one";
const doc3: Document = [ doc1, doc2 ];
const doc = Math.random() < 0.5 ? doc1 : (Math.random() < 0.5 ? doc2 : doc3);
if (typeof doc === "number") {
doc - 1;
} else if (typeof doc === "string") {
doc.toUpperCase();
} else {
// fails with "Property 'map' does not exist on type 'DocumentArray'"
doc.map(d => d);
}
Dies kann durch Änderung der Definition von DocumentArray gelöst werden:
interface DocumentArray extends Array<ScalarDocument | DocumentArray> {}
Anscheinend sind zirkuläre Typreferenzen erlaubt: http: // stackoverflow.com/questions/24444436/circular-type-references-in-maschinenschrift – btk