Skip to content

Property Type inference problem when picking property with index key type #39945

Closed

Description

TypeScript Version: 3.9.5

Search Terms:

  • [K in keyof T]: T[K] extends V | undefined | null
  • type T[keyof T] does not
  • infer property type

Code

given the following 2 structures, they look like the same, i.e. a parent-child relationship

interface Category {
  children?: this[],
  parent?: this
}

interface Node {
  items?: this[],
  parent?: this
}

I want to access them the same way, by giving the relative property names, e.g. 'children'/'items' for child relation and 'parent' for parent relation, like this:

let category: Category = {};
// access children and parent of category
handle(category, 'children', 'parent'); //!! <- inference problem here

let node: Node = {};
// access items and parent of node
handle(node, 'items', 'parent'); //!! <- inference problem here

here is how I define the handle method with some helpers

type Nullable<T> = T | undefined | null;

type PickKey<T, V> = keyof {
  [K in keyof T]: T[K] extends Nullable<V> ? K : never
};

export function handle<
  T extends Record<PickKey<T, T[]>, Nullable<T[]>
    & Record<PickKey<T, T>, Nullable<T>>
  >
>(
  tree: T,
  childrenKey: PickKey<T, T[]>,
  parentKey: PickKey<T, T>,
) {
  let parent = tree[parentKey];
  if (parent) {
    let siblings = parent[childrenKey];
  }
  let children = tree[childrenKey];
  if (children) {
    for (let ii = 0; ii < children.length; ii++) {
      const child = children[ii];
    }
  }
}

Expected behavior:

It should compile

Actual behavior:

Argument of type 'Category' is not assignable to parameter of type 'Record<"children" | "parent", Category[] & Record<"children" | "parent", Nullable<Category>>>'.
  Types of property 'children' are incompatible.
    Type 'Category[] | undefined' is not assignable to type 'Category[] & Record<"children" | "parent", Nullable<Category>>'.
      Type 'undefined' is not assignable to type 'Category[] & Record<"children" | "parent", Nullable<Category>>'.
        Type 'undefined' is not assignable to type 'Category[]'.ts(2345)

Playground Link:

Related Issues:

it is related, but not really the same
#38646

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions