Ruben
Ruben

Reputation: 1749

Nested TypeScript object with variable keys

I have a JavaScript method that automatically imports JSON Schemas depending on directory structure. This means that I have a file located at /path/to/my/file.json, which is then loaded in schemas.path.to.my.file.

I use the following TypeScript definition to use my code in TypeScript, but to no avail. It keeps giving me errors about no index signature, even though, there seems to be one.

import jsonschema = require("jsonschema");

interface NestedSchemas {
    [key: string]: NestedSchemas | jsonschema.Schema;
}

interface MySchemas {
    validator: jsonschema.Validator;
    initialized: boolean;
    walk: Promise<NestedSchemas>;
    schemas: NestedSchemas;
}

declare var _: MySchemas;
export = _;

When I then try to use my code, I see the following pop up by my linter:

enter image description here

The points of interest are the fact that it first shows Schema and then NestedSchemas (while defined the other way around in the interface), and that it doesn't try to resolve it anyway, since it's a string key.

What am I doing wrong here?

Upvotes: 1

Views: 7426

Answers (1)

ben
ben

Reputation: 3568

You can simplify the issue like this: This gives the warning:

interface NestedSchemas {
    [key: string]: NestedSchemas | string;
}
const themas: NestedSchemas = {};
themas['0.1'].foo.bar.baz

while this don't:

interface NestedSchemas {
    [key: string]: NestedSchemas;
}
const themas: NestedSchemas = {};
themas['0.1'].foo.bar.baz

This is because typescript doesn't know if themas['0.1'] will be of type NestedSchemas or string.

  • You can circumvent that by casting:

(((themas['0.1'] as NestedSchemas).foo as NestedSchemas).bar as NestedSchemas).baz

(I admit, not very elegant)

  • Or you may use a User-Defined Type Guards

You should read https://www.typescriptlang.org/docs/handbook/advanced-types.html for details about it.

Upvotes: 5

Related Questions