0

I try to pass a parentNode of a node to my getStyleComputedProperty function.

But got an error:

Argument of type '(Node & ParentNode) | null' is not assignable to parameter of type 'Element'. Type 'null' is not assignable to type 'Element'.

Code here:

type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T];
type Property = NonFunctionPropertyNames<CSSStyleDeclaration>;
export const getStyleComputedProperty = (ele: Element, property: Property): string => {
  const css = window.getComputedStyle(ele, null);
  return css[property];
};

const div = document.createElement('div')
getStyleComputedProperty(div.parentNode, 'position') // tsc throw error

I know I can use type cast like this div.parentNode as Element to pass the TSC type check. But I wonder how can I make the type correct without the type cast.

Here is TypeScript Playground

Lin Du
  • 88,126
  • 95
  • 281
  • 483

1 Answers1

4

Try to use parentElement instead of parentNode:

type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T];
type Property = NonFunctionPropertyNames<CSSStyleDeclaration>;
export const getStyleComputedProperty = (ele: Element, property: Property): string => {
  const css = window.getComputedStyle(ele, null);
  return css[property];
};

const div = document.createElement('div')
if (div.parentElement) {
  getStyleComputedProperty(div.parentElement, 'position')
}

Here you can find the difference between those two

You are right, using type casting as should be the last resort

  • It seems the behaviours of parentNode and parentElement are not the same. So I worry it will break for runtime. – Lin Du Feb 20 '21 at 11:19