Pesquisa de site

digitando - Há uma maneira de "extrair" o tipo de uma propriedade de interface do TypeScript?


Vamos supor que haja um arquivo de tipagem para a biblioteca X que inclui algumas interfaces.

interface I1 {
    x: any;
}
    
interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

Para trabalhar com esta biblioteca, preciso passar um objeto que seja exatamente do mesmo tipo que I2.y. Posso, é claro, criar uma interface idêntica nos meus arquivos de origem:

interface MyInterface {
    a: I1,
    b: I1,
    c: I1
}

let myVar: MyInterface;

mas então eu fico com o ônus de mantê-lo atualizado com o da biblioteca, além disso, ele pode ser muito grande e resultar em muita duplicação de código.

Portanto, existe alguma maneira de "extrair" o tipo desta propriedade específica da interface? Algo semelhante a let myVar: typeof I2.y (o que não funciona e resulta no erro "Cannot find name I2").


Editar: depois de brincar um pouco no TS Playground, percebi que o código a seguir consegue exatamente o que eu quero:

declare var x: I2;
let y: typeof x.y;

No entanto, isso requer que uma variável redundante x seja declarada. Estou procurando uma maneira de conseguir isso sem essa declaração.

Resposta #1

Não era possível antes, mas felizmente agora é, desde a versão 2.1 do TypeScript. Ela foi lançada em 7 de dezembro de 2016 e introduz tipos de acesso indexado, também chamados de tipos de consulta.

A sintaxe se parece com o acesso a elementos, mas é escrita no lugar dos tipos. Então, no seu caso:

interface I1 {
    x: any;
}

interface I2 {
    y: {
        a: I1,
        b: I1,
        c: I1
    }
    z: any
}

let myVar: I2['y'];  // indexed access type

Agora myVar tem o tipo de I2.y.

Confira no TypeScript Playground.

Resposta #2

Para expandir a resposta aceita, você também pode atribuir o tipo usando a palavra-chave type e usá-lo em outros lugares.

// Some obscure library
interface A {
  prop: {
    name: string;
    age: number;
  }
}

// Your helper type
type A_Prop = A['prop']

// Usage
const myThing: A_prop = { name: 'June', age: 29 };

Resposta #3

Apenas um exemplo de extração de um tipo literal do tipo de objeto união:

type Config = {
    key: "start_time",
    value: number,
} | {
    key: "currency",
    value: string,
}

export type ConfigKey = Config["key"];
// "start_time"|"currency"

Resposta #4

keyof Colors retornará uma lista de todas as chaves "white" | "black". Quando essa lista de chaves é passada para a interface Colors, o tipo será todos os valores das chaves fornecidas, "#fff" | #000.

interface Colors {
  white: "#fff"
  black: "#000"
}

type ColorValues = Colors[keyof Colors]
// ColorValues = "#fff" | "#000"

Artigos relacionados