-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Description
The node.parent value returns a ContainerWithChildren type. This interface extends Node directly, so it is not possible to determine at compile-type which type of node is the parent node just by looking at type. It is only possible to do at runtime, and this makes the interface not very useful for Typescript.
Example TS code [stackblitz]:
import postcss from 'postcss';
const { root } = postcss([]).process('@a{.b{}}').sync();
const [atRule] = root.nodes;
if (atRule.type !== 'atrule') throw new Error('not at-rule');
const [rule] = atRule.nodes ?? [];
if (rule.type !== 'rule') throw new Error('not rule');
const { parent } = rule;
switch (parent?.type) {
case 'rule':
case 'comment':
case 'atrule':
case 'decl':
case 'root':
case undefined:
console.log('yay');
default:
// This fails because `parent` is of type `ContainerWithChildren` which is
// an interface that extends `Node` rather than being a sumtype.
const impossible: never = parent;
}Arguably, the ContainerWithChildren interface should not extend Container. Instead it should be declared something like:
type ContainerWithChildren<T> = (Root | AtRule | Rule) & Container<T>;(I haven't verified this type, but it should be something along these lines)
Metadata
Metadata
Assignees
Labels
No labels