Closed
Description
openedon Aug 7, 2020
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
Labels
No labels