typescript

Referencing leaves in nested object with typed leaves


I have a nested object where I want to type the values in the object and then assign the values in the object to variables, or pass then as parameters to functions.

It's easy enough to type the object, but I can't reference it's values without an error. How do I fix this?

export type Nodes<T> = {
    [n: string]: T | Nodes<T>
}

type VALUE = 'X'|'Y' ; 

const obj : Nodes<VALUE> = {
  a: {
    b: 'X'
  }
};


const fn = (v: VALUE) => v;

const v: VALUE = obj.a.b; // <== Property 'b' does not exist on type 'VALUE | Nodes<VALUE>'. Property 'b' does not exist on type '"X"'.(2339)
fn(obj.a.b);  // <== Property 'b' does not exist on type 'VALUE | Nodes<VALUE>'. Property 'b' does not exist on type '"X"'.(2339)

Solution

  • You should use satisfies so TS would infer exact node type (T or Node<T>) for each node, otherwise there's no common known property for T | Node<T> like you try to use with b:

    Playground

    const obj = {
      a: {
        b: 'X'
      }
    } satisfies Nodes<VALUE>;