BartD
BartD

Reputation: 81

How to type nested objects - Typescript

I have a probem with typing this line of code initialState[a][b].

I got this error:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ food: { pizza: boolean; chicken: boolean; }; transport: { bus: boolean; car: boolean; }; }'

function testTypescript(a: string, b: string) {
    const initialState = {
        food: {
            pizza: false,
            chicken: false,
        },
        transport: {
            bus: false,
            car: false,
        },
    };
    const newData = !initialState[a][b]; // How can I type this line?
    const newState = { ...initialState, [a]: newData };
    return newState;
}

Upvotes: 0

Views: 254

Answers (3)

serg Ks
serg Ks

Reputation: 11

Any nesting

type initial = {
  [key: string] :  any;
}

function testTypescript(a: string, b: string) {
    const initialState : initial = {
        food: {
            pizza: false,
            chicken: false,
        },
        transport: {
            bus: false,
            car: false,
        },
    };
    const newData = !initialState[a][b]; // How can I type this line?
    const newState = { ...initialState, [a]: newData };
    return newState;
}

Upvotes: 0

Yury Tarabanko
Yury Tarabanko

Reputation: 45106

You can use some generics. Play

type State = {
  food: {
    pizza: boolean;
    chicken: boolean;
  };

  transport: {
    bus: boolean;
    car: boolean;
  }
}

function testTypescript<T extends keyof State>(a: T, b: keyof State[T]) {
    const initialState: State = {
        food: {
            pizza: false,
            chicken: false,
        },
        transport: {
            bus: false,
            car: false,
        },
    };
    const newData = !initialState[a][b]; // How can I type this line?
    const newState = { ...initialState, [a]: newData };
    return newState;
}

// @ts-expect-error
testTypescript('notThere', 'value')

// @ts-expect-error
testTypescript('food', 'rice')

testTypescript('transport', 'bus')

Upvotes: 2

OTMANƏ EL
OTMANƏ EL

Reputation: 51

function testTypescript(a: string, b: string) {
    const initialState: { [a: string]: { [b: string]: boolean; } } = {
        food: {
            pizza: false,
            chicken: false,
        },
        transport: {
            bus: false,
            car: false,
        },
    };
    const newData: boolean = !initialState[a][b];
    const newState = { ...initialState, [a]: { [b]: newData } };
    return newState;
}

Upvotes: 1

Related Questions