Test auf Array vom Typ String in TypeScript


91

Wie kann ich testen, ob eine Variable ein Array von Zeichenfolgen in TypeScript ist? Etwas wie das:

function f(): string {
    var a: string[] = ["A", "B", "C"];

    if (typeof a === "string[]")    {
        return "Yes"
    }
    else {
        // returns no as it's 'object'
        return "No"
    }
};

TypeScript.io hier: http://typescript.io/k0ZiJzso0Qg/2

Bearbeiten: Ich habe den Text aktualisiert, um nach einem Test für Zeichenfolge [] zu fragen. Dies war bisher nur im Codebeispiel der Fall.



Da TypeScript nur zu JavaScript kompiliert wird, können die Antworten durch Suchen nach einer JavaScript-Lösung gefunden werden. Außerdem lohnt es sich, einige der Antworten zu sehen, da die Antwort vom Host abhängt und davon, wie sie verwendet und weitergegeben wird.
— WiredPrairie

Antworten:


158

Sie können string[]im allgemeinen Fall nicht testen, aber Sie können Arrayganz einfach das gleiche wie in JavaScript https://stackoverflow.com/a/767492/390330 testen

Wenn Sie speziell für stringArray wollen , können Sie etwas tun wie:

if (Array.isArray(value)) {
   var somethingIsNotString = false;
   value.forEach(function(item){
      if(typeof item !== 'string'){
         somethingIsNotString = true;
      }
   })
   if(!somethingIsNotString && value.length > 0){
      console.log('string[]!');
   }
}

instanceof Arrayschlägt fehl, wenn Arrays über Frames hinweg überprüft werden. Bevorzugen Array.isArray: twitter.com/mgechev/status/1292709820873748480
— axmrnv

@axmrnv Stimme voll und ganz zu 🌹
— basarat

58

Eine weitere Option ist Array.isArray ()

if(! Array.isArray(classNames) ){
    classNames = [classNames]
}

4
Dies prüft jedoch nicht, ob die Elemente vom Typ sind string.
— Ixx

4
Ja. Dann benötigen Sie eine zusätzliche Überprüfung. Array.isArray(classNames) && classNames.every(it => typeof it === 'string')
— Grigson

@grigson Wie wäre es mit Leistung bei der Überprüfung von mehr als 400 Ergebnissen? Sollte ich diese Art der Typprüfung überdenken, nur das erste Kind überprüfen oder ist es sicher, dieses "alles" zu verwenden?
— Giovannipds

1
@giovannipds Bitte überprüfen Sie die Antwort von asmironov .
— Dinei

22

Hier ist die bisher prägnanteste Lösung:

function isArrayOfStrings(value: any): boolean {
   return Array.isArray(value) && value.every(item => typeof item === "string");
}

Beachten Sie, dass value.everyzurückkehren truefür ein leeres Array. Wenn Sie falsefür ein leeres Array zurückkehren müssen, sollten Sie value.lengthder Bedingungsklausel Folgendes hinzufügen :

function isNonEmptyArrayOfStrings(value: any): boolean {
    return Array.isArray(value) && value.length && value.every(item => typeof item === "string");
}

In TypeScript gibt es keine Informationen zum Laufzeit-Typ (und dies wird auch nicht der Fall sein, siehe TypeScript-Entwurfsziele> Nicht-Ziele , 5). Daher gibt es keine Möglichkeit, den Typ eines leeren Arrays abzurufen. Für ein nicht leeres Array können Sie lediglich den Typ seiner Elemente nacheinander überprüfen.


5

Ich weiß, dass dies beantwortet wurde, aber TypeScript hat Type Guards eingeführt: https://www.typescriptlang.org/docs/handbook/advanced-types.html#typeof-type-guards

Wenn Sie einen Typ haben wie: Object[] | string[]und was unter bestimmten Bedingungen bedingt zu tun ist, können Sie diesen Typschutz verwenden:

function isStringArray(value: any): value is string[] {
  if (value instanceof Array) {
    value.forEach(function(item) { // maybe only check first value?
      if (typeof item !== 'string') {
        return false
      }
    })
    return true
  }
  return false
}

function join<T>(value: string[] | T[]) {
  if (isStringArray(value)) {
    return value.join(',') // value is string[] here
  } else {
    return value.map((x) => x.toString()).join(',') // value is T[] here
  }
}

Es gibt ein Problem mit der Eingabe eines leeren Arrays als string[], aber das ist möglicherweise in Ordnung


10
Das return falsein der forEachhat keine Wirkung.
— Ishtar

4

Sie können es einfach Array.prototype.some()wie folgt tun .

const isStringArray = (test: any[]): boolean => {
 return Array.isArray(test) && !test.some((value) => typeof value !== 'string')
}
const myArray = ["A", "B", "C"]
console.log(isStringArray(myArray)) // will be log true if string array

Ich glaube, dieser Ansatz ist besser als andere. Deshalb poste ich diese Antwort.

Update zu Sebastian Vittersøs Kommentar

Hier können Sie auch verwenden Array.prototype.every().

const isStringArray = (test: any[]): boolean => {
 return Array.isArray(test) && test.every((value) => typeof value === 'string')
}

1
Anstatt hier an zwei Stellen zu test.every(value => typeof value === 'string')
— negieren

1
@ SebastianVittersø Danke für den NICE Vorschlag. Ich habe meine Antwort aktualisiert.
— Sudarshana Dayananda

2

Versuche dies:

if (value instanceof Array) {
alert('value is Array!');
} else {
alert('Not an array');
}

6
Anstatt eine andere Antwort zu kopieren, weisen Sie bitte nur auf das Duplikat als Kommentar hin, zumal dies nicht in allen Fällen funktioniert.
— WiredPrairie

Dies überprüft nur den Haupttyp, nicht jedes untergeordnete Array.
— Giovannipds

0

Hier gibt es ein kleines Problem, weil die

if (typeof item !== 'string') {
    return false
}

wird den foreach nicht aufhalten. Die Funktion gibt also true zurück, auch wenn das Array keine Zeichenfolgenwerte enthält.

Das scheint für mich zu wok:

function isStringArray(value: any): value is number[] {
  if (Object.prototype.toString.call(value) === '[object Array]') {
     if (value.length < 1) {
       return false;
     } else {
       return value.every((d: any) => typeof d === 'string');
     }
  }
  return false;
}

Grüße, Hans

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.