Soy nuevo en TypeScript y he probado varias formas de escribir esto, pero tengo problemas con las firmas de índice. ¿Cómo debería verse la interfaz?

interface MyConfig {
...
}

// someVar can be any string
let someVar = "dynamicKey";

// the structure of the object cannot change
const config: MyConfig = {
  myObj: {
    [someVar]: {
      firstProp: 'some text',
      secondProp: 'some text',
    },
    thirdProp: 'some text',
  },
};


1
phifa 29 oct. 2020 a las 11:28

1 respuesta

La mejor respuesta

Si conoce el valor o los valores exactos de la variable someVar, puede tener una interfaz estricta como:

interface MyConfig {
    myObj: {
        SomeKey: {
            firstProp: string
            secondProp: string
        },
        thirdProp: string
    }
}

Entonces puedes usar:

const someVar = "SomeKey";

const config: MyConfig = {
    myObj: {
        [someVar]: {
            firstProp: 'some text',
            secondProp: 'some text',
        },
        thirdProp: 'some text',
    },
};

Pero si desea que someVar sea dinámico, es un poco complicado. Para eso, le recomendaría que mueva la parte dinámica a un bloque separado, para que pueda usar:

interface MyConfig {
    myObj: {
        dynamic: {
            [key: string]: {
                firstProp: string
                secondProp: string
            }
        },
        thirdProp: string
    }
}

const someVar = "SomeKey";
const config: MyConfig = {
    myObj: {
        dynamic: {
            [someVar]: {
                firstProp: 'some text',
                secondProp: 'some text',
            },
        },
        thirdProp: 'some text',
    },
};

Y finalmente, si tiene someVar dinámico y no puede cambiar la estructura de datos. puede utilizar lo siguiente:

interface MyConfig {
    myObj: ({
        [key: string]: {
            firstProp: string
            secondProp: string
        } | string
    } & {
        thirdProp: string
    })
}
const someVar: string = "SomeKey";

const config: MyConfig = {
    myObj: {
        [someVar]: {
            firstProp: 'some text',
            secondProp: 'some text',
        },
        thirdProp: 'some text',
    },
};

// String
console.log(config.myObj.thirdProp.trim())

// Error, union string | object
console.log(config.myObj.abc.firstProp)

if (typeof config.myObj.abc === 'object') {
    // string
    console.log(config.myObj.thirdProp.trim())
    // string
    console.log(config.myObj.abc.firstProp.trim())
}

En este ejemplo, usamos una firma de índice mecanografiado + especificamos propiedades conocidas. También puede notar algo extraño: la firma del índice tiene la unión object | string. Esto se debe a la limitación del texto mecanografiado:

Tan pronto como tenga una firma de índice de cadena, todos los miembros explícitos también deben cumplir con esa firma de índice. Esto es para brindar seguridad para que cualquier acceso a la cadena dé el mismo resultado.

Referencia: Cómo combinar propiedades de interfaz declaradas con firma de índice personalizada

1
KiraLT 30 oct. 2020 a las 12:11