Jak mogę zdefiniować tablicę obiektów?


198

Tworzę tablicę obiektów w TypeScript:

 userTestStatus xxxx = {
    "0": { "id": 0, "name": "Available" },
    "1": { "id": 1, "name": "Ready" },
    "2": { "id": 2, "name": "Started" }
 };

Czy ktoś może mi powiedzieć, jak poprawnie zadeklarować jego typ? Czy jest możliwe zrobienie inline, czy potrzebowałbym dwóch definicji?

Chcę zastąpić xxxdeklarację typu, aby później TypScript ostrzegał mnie, gdybym userTestStatus[3].nammmeprzez pomyłkę użył czegoś takiego .

Odpowiedzi:


281

Lepiej jest użyć natywnej tablicy zamiast literału obiektu o właściwościach liczbowych, aby numeracja (a także wiele innych funkcji tablicowych) była dostępna od ręki.

To, czego szukasz tutaj, to wbudowana definicja interfejsu dla tablicy, która definiuje każdy element w tej tablicy, początkowo obecny lub wprowadzony później:

let userTestStatus: { id: number, name: string }[] = [
    { "id": 0, "name": "Available" },
    { "id": 1, "name": "Ready" },
    { "id": 2, "name": "Started" }
];

userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]

Jeśli od razu inicjujesz tablicę wartościami, jawna definicja typu nie jest koniecznością; TypeScript może automatycznie wywnioskować większość typów elementów z początkowego przypisania:

let userTestStatus = [
    { "id": 0, "name": "Available" },
    ...
];

userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]

4
Możesz także zadeklarować tablicę obiektów w ten sposób:let someArray: Array<{ id: number, name: string }> = []
Alexander Kim

75

To, co masz powyżej, to obiekt, a nie tablica.

Aby tablica używała [i ]otaczała obiekty.

userTestStatus = [
  { "id": 0, "name": "Available" },
  { "id": 1, "name": "Ready" },
  { "id": 2, "name": "Started" }
];

Poza tym TypeScript jest nadzbiorem JavaScript, więc cokolwiek jest poprawne, JavaScript będzie poprawnym TypeScript, więc żadne inne zmiany nie będą potrzebne.

Wyjaśnienie informacji zwrotnych z PO ... potrzebuje definicji dla opublikowanego modelu

Można użyć typów zdefiniowanych tutaj do reprezentowania modelu obiektowego:

type MyType = {
    id: number;
    name: string;
}

type MyGroupType = {
    [key:string]: MyType;
}

var obj: MyGroupType = {
    "0": { "id": 0, "name": "Available" },
    "1": { "id": 1, "name": "Ready" },
    "2": { "id": 2, "name": "Started" }
};
// or if you make it an array
var arr: MyType[] = [
    { "id": 0, "name": "Available" },
    { "id": 1, "name": "Ready" },
    { "id": 2, "name": "Started" }
];

Przepraszam, może moje pytanie nie było jasne. Chciałem znaleźć definicję userTestStatus.

1
@Marilou Zazwyczaj definicję można uzyskać po najechaniu kursorem na userTestStatuszmienną w swoim ulubionym IDE ... pokazuje boisko TypeScript { id: number, name: string; }[]. Możesz zawinąć to w interfejs, jeśli chcesz interface NameThis { id: number, name: string; }i NameThis[]jako typ tablicy.
Fenton

Próbowałem tego, ale daje mi to kilka błędów. Myślę jednak, że to coś takiego: userTestStatus: {id: number, name: string; } [] = {"0": {"id": 0, "name": "Available"}, "1": {"id": 1, "name": "Ready"},

W swoim przykładzie definiowania var arr: MyTypenie używałbyś deklaracji nazwy / indeksu właściwości, takich jak "0": { … }; w tym momencie użyłbyś po prostu literału obiektu.
gfullam

@gfullam masz rację, zaktualizowałem swoją odpowiedź (to była szybka nieostrożna edycja)
Brocco

34

Niektóre tslintreguły wyłączają użycie [], przykładowej wiadomości:Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead.

Następnie napiszesz to tak:

var userTestStatus: Array<{ id: number, name: string }> = Array(
    { "id": 0, "name": "Available" },
    { "id": 1, "name": "Ready" },
    { "id": 2, "name": "Started" }
);

2
Najbardziej praktyczne podejście kiedykolwiek. jest to proste i bezpośrednie rozwiązanie dla prostych przypadków użycia macierzy. Weź moją +1
Julio Vedovatto

17

To, czego naprawdę chcesz, może być po prostu wyliczeniem

Jeśli szukasz czegoś, co zachowuje się jak wyliczenie (ponieważ widzę, że definiujesz obiekt i dołączasz sekwencyjny identyfikator 0, 1, 2 i zawiera on pole nazwy, którego nie chcesz przeliterować (np. Nazwa vs naaame) , lepiej jest zdefiniować wyliczenie, ponieważ sekwencyjny identyfikator jest obsługiwany automatycznie i zapewnia weryfikację typu od razu po wyjęciu z pudełka.

enum TestStatus {
    Available,     // 0
    Ready,         // 1
    Started,       // 2
}

class Test {
    status: TestStatus
}

var test = new Test();
test.status = TestStatus.Available; // type and spelling is checked for you,
                                    // and the sequence ID is automatic

Powyższe wartości zostaną automatycznie zamapowane, np. „0” dla „Dostępne”, i można uzyskać do nich dostęp za pomocą TestStatus.Available. A maszynopis wymusi ten typ, gdy go przekażesz.

Jeśli nalegasz na zdefiniowanie nowego typu jako tablicy typu niestandardowego

Chcieliście tablicy obiektów (nie dokładnie obiektu z kluczami „0”, „1” i „2”), więc zdefiniujmy najpierw typ obiektu, a następnie typ tablicy zawierającej.

class TestStatus {
    id: number
    name: string

    constructor(id, name){
        this.id = id;
        this.name = name;
    }
}

type Statuses = Array<TestStatus>;

var statuses: Statuses = [
    new TestStatus(0, "Available"),
    new TestStatus(1, "Ready"),
    new TestStatus(2, "Started")
]

Przepraszam, może moje pytanie nie było jasne. Chciałem znaleźć definicję userTestStatus, aby Typescript pozwolił mi sprawdzić, gdzie jest używany, i na przykład nie mogłem wprowadzić userTestStatus [1] .naaaame.

Chciałem znaleźć coś do umieszczenia między „userTestStatus” a „=”. W ten sam sposób, w jaki mógłbym wstawić ciąg lub liczbę, aby powiedzieć, jaki typ ma zmienna. Coś takiego jak Brocco, ale właśnie z jedną linią, jeśli to możliwe.

-1

Możesz także spróbować

    interface IData{
        id: number;
        name:string;
    }

    let userTestStatus:Record<string,IData> = {
        "0": { "id": 0, "name": "Available" },
        "1": { "id": 1, "name": "Ready" },
        "2": { "id": 2, "name": "Started" }
    };

Aby sprawdzić, jak działa zapis: https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

Tutaj w naszym przypadku Record służy do deklarowania obiektu, którego kluczem będzie ciąg znaków i którego wartość będzie typu IData, więc teraz zapewni nam inteligencję, kiedy spróbujemy uzyskać dostęp do jego właściwości i wyrzuci błąd typu na wypadek, gdybyśmy spróbowali coś takiego jak userTestStatus [0] .nameee


powinieneś podać więcej informacji o tym, dlaczego to rozwiązuje problem
Cornel Raiu,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.