Pesquisa de site

Assinatura de índice do Typescript com propriedades conhecidas de tipos mistos


Como especificar uma assinatura de índice com propriedades conhecidas de tipo fixo e todas as outras propriedades de um tipo diferente. O exemplo a seguir funciona como esperado com as any, mas falha quando todas as propriedades são especificadas:

type S = {
    s?: number;
} 
type H = {
    [key: string]: Function | undefined;
}
type Handler = S & H


const h1: Handler = {} as any;

/* Ok */
h1.sadwa?.()
h1.s = 2;


/* Not ok */
const h2: Handler = {
    s:  22,
    f: ()=>{}
}
h2.f()
h2.s = 2;

https://www.typescriptlang.org/play?#code/C4TwDgpgBAylC8UDeAoK6oGcD8AuKAdgK4C2ARhAE4DcKAvlCqJFABILJoYDaA1hCHyZglAJYEA5gF18AMSIEAxsFEB7AlAA+UBQBMIAM3ERdtOk3DRWAQwK6ANlQ5wAZGxQfF64VAAWARnwbO0dKDiQGa0woWxBaFAB6ACooAHleKCSElACAOkxrXQB3a2xcgAoAShz-fI4AJnjElIA5VWAoVQyslC8CH196oNsHJ0RUDCx8KHr6gBoudAN8KvgAPgj6HPrcgyrtusRGoA

Resposta #1

Eu estive lendo sobre o que a Assinatura de Índice pode fazer, o que ela é e o que ela não pode fazer.

A única maneira de você fazer este exemplo funcionar é se o tipo fornecido no valor da assinatura de índice englobar todos os outros tipos especificados no objeto

por exemplo:

type S = {
    s?: number;
} 
type H = {
    [key: string]: Function | undefined | number;
}
type Handler = S & H

// Incedentally the above is the same as this type
type AnotherHandler = {
    s?: number;
    [key: string]: Function | undefined | number
}

// Works just fine
const h2: Handler = {
    s:  22,
    f: ()=>{}
}
h2.f()
h2.s = 2;

Isso tem a ver com o que é uma Assinatura de Índice em princípio. O índice de um objeto é uma folha de referência para tudo o que o objeto contém. Sua assinatura é garantida para corresponder a todos os tipos de valor no objeto. Essa explicação é um pouco simplificada, mas funciona para este exemplo.

Se você não quiser fazer isso, mas quiser pelo menos contornar o problema com o tipo, você poderia contornar a verificação de tipo declarando o objeto sem um tipo, como você fez com o h1, e então aproveitar a verificação de tipo mais relaxada que acontece quando você usa esse objeto em um lugar que exige o seu tipo (A regra exata é que, desde que o objeto que você está usando tenha pelo menos um par chave:valor devidamente tipado em comum com o tipo em uso, quaisquer outros tipos misturados não falharão na verificação)