javascript - Olika typer för Typescript indexsignatur


Jag har följande interface.

interface IDetails {
  name: string;
  age: number;
}

interface IConfig {
  appName: string;
  userDetails: IDetails;
  [key: string]: string | IDetails
}

const details: IConfig = {
  appName: 'test',
  userDetails: {
    name: 'xyz',
    age: 67,
  },
}

const t: string = 'userDetails'
const name: string = details[t].name
//                              ^^^^ 
// throws the following error
//
// Property 'name' does not exist on type 'string | IDetails'.
//  Property 'name' does not exist on type 'string'.

När jag försöker tilldela flera typer/gränssnitt till nyckelsignaturen får jag detta fel. Jag vet att jag kan använda [key: string]: any. Men jag vill inte generalisera det. Finns det något sätt att få detta att fungera?

Länk till TypeScript Playground

Svar #1

Om du ska komma åt egenskaperna hos details dynamiskt, då är det bäst att använda typvakter:

function isDetails(obj: string | IDetails): obj is IDetails {
    return Object.keys(obj).length === 2 && typeof obj["name"] === "string" && typeof obj["age"] === "number";
}

Då kan du göra:

if (isDetails(details[t])) {
    // details[t].name should be fine with the compiler
}