Como posso definir uma matriz de objetos?


197

Estou criando uma matriz de objetos no TypeScript:

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

Alguém pode me dizer como eu poderia declarar seu tipo corretamente? É possível fazer inline ou eu precisaria de duas definições?

Eu estou olhando para substituir o xxxcom uma declaração de tipo, para que mais tarde TypeScript me alertaria se eu usasse algo como userTestStatus[3].nammmepor engano.

Respostas:


279

É melhor usar uma matriz nativa em vez de um literal de objeto com propriedades semelhantes a números, para que a numeração (assim como várias outras funções da matriz) sejam resolvidas prontamente.

O que você está procurando aqui é uma definição de interface embutida para sua matriz que define todos os elementos dessa matriz, estejam inicialmente presentes ou introduzidos posteriormente:

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 [...]

Se você estiver inicializando sua matriz com valores imediatamente, a definição explícita de tipo não é uma necessidade; O TypeScript pode inferir automaticamente a maioria dos tipos de elementos a partir da atribuição inicial:

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

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

4
Além disso, você pode declarar uma matriz de objetos desta maneira:let someArray: Array<{ id: number, name: string }> = []
Alexander Kim

74

O que você tem acima é um objeto, não uma matriz.

Para fazer uma matriz, use [& ]para cercar seus objetos.

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

Além disso, o TypeScript possui um superconjunto de JavaScript; portanto, o que for válido, o JavaScript será válido, assim como nenhuma outra alteração.

Esclarecimento de feedback do OP ... precisa de uma definição para o modelo publicado

Você pode usar os tipos definidos aqui para representar seu modelo de objeto:

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" }
];

Desculpe, talvez minha pergunta não esteja clara. O que eu queria fazer era encontrar uma definição para userTestStatus.

1
@ Marilou Geralmente, você pode obter a definição simplesmente passando o mouse sobre a userTestStatusvariável em seu IDE favorito ... mostra o playground TypeScript { id: number, name: string; }[]. Você pode agrupar isso em uma interface, se quiser, interface NameThis { id: number, name: string; }e NameThis[]como o tipo de matriz.
Fenton

Eu tentei isso, mas isso me dá alguns erros. No entanto, acho que é algo como eu quero: userTestStatus: {id: número, nome: string; } [] = {"0": {"id": 0, "nome": "Disponível"}, "1": {"id": 1, "nome": "Pronto"},

No seu exemplo de definição var arr: MyType, você não usaria as declarações de nome / índice de propriedade como "0": { … }; você usaria apenas o objeto literal neste momento.
Gfullam

@gfullam você está correto, eu atualizei a minha resposta (que era uma edição descuidada rápida)
Brocco

34

Algumas tslintregras estão desativando o uso de [], mensagem de exemplo:Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead.

Então você escreveria como:

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

2
Abordagem mais prática de sempre. é uma solução simples e direta para casos de uso de matriz simples. Tome meu +1
Julio Vedovatto

16

O que você realmente quer pode ser simplesmente uma enumeração

Se você estiver procurando por algo que se comporte como uma enumeração (porque vejo que você está definindo um objeto e anexando um ID sequencial 0, 1, 2 e contém um campo de nome que você não deseja digitar errado (por exemplo, nome vs naaame) , é melhor definir uma enumeração porque o ID seqüencial é resolvido automaticamente e fornece a verificação de tipo para você imediatamente.

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

Os valores acima serão mapeados automaticamente, por exemplo, "0" para "Disponível", e você pode acessá-los usando TestStatus.Available. E o Typecript reforçará o tipo quando você passar por aí.

Se você insistir em definir um novo tipo como uma matriz do seu tipo personalizado

Você queria uma matriz de objetos (não exatamente um objeto com as teclas "0", "1" e "2"); portanto, vamos definir o tipo do objeto, primeiro, depois o tipo de uma matriz contendo.

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")
]

Desculpe, talvez minha pergunta não esteja clara. O que eu queria fazer era encontrar uma definição para userTestStatus para que o Typecript me permitisse verificar onde é usado e, por exemplo, não pude inserir userTestStatus [1] .naaaame.

Eu queria encontrar algo para colocar entre o "userTestStatus" e o "=". Da mesma maneira que eu poderia colocar string ou número lá para dizer qual o tipo da variável. Algo como Brocco acabou de fazer, mas com apenas uma linha, se isso for possível.

-1

Você também pode tentar

    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" }
    };

Para verificar como o registro funciona: https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

Aqui, no nosso caso, Record é usado para declarar um objeto cuja chave será uma string e cujo valor será do tipo IData. Agora, ele nos fornecerá inteligência quando tentaremos acessar sua propriedade e lançará um erro de tipo caso tentemos algo como userTestStatus [0] .nameee


você deve dar mais informações a respeito de porque isso resolve o problema na mão
Cornel Raiu
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.