postcss: `Result.root` that is typed as `Document | Root` breaks the semantics of the `root` property

Ever since the addition of Document I’ve been “arguing” with the types of PostCSS a lot more. I’ve also been unable to add meaningful support for any syntax that makes use of the Document node because those syntax plugins have blocking issues that prevent real support.

Any plugin works equally bad or well as it did before this addition and none leverage this new node type.

So from my perspective the addition of Document isn’t beneficial.

I feel that the current implementation isn’t quite right.
I don’t know what should be changed to fix this.


This specific issue is about this code :

https://github.com/postcss/postcss/blob/a0a82d3530ce7dfbfe1f12aa76c20f1b3f95eb7c/lib/result.d.ts#L144

What I want to do :

  • parse a stylesheet that is a foo.css file
  • access the Root node

I already know that it is a Root node but now the type system is complaining and saying that it can be a Document node.

I can override this and tell TypeScript that it really is a Root node.
But what if someone uses one of the syntaxes that does return a Document in this case.

Which steps should I take :

  • warn on Document nodes in Result.root?
  • throw an error?
  • traverse the Document nodes in search of Root nodes?

I think result.root must always return a Root node.
Never a Document node.

Maybe a new property can be added to expose Document nodes?

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 17 (17 by maintainers)

Most upvoted comments

The process().root fix was released in 8.4.28.

Yes, in Once there is no other way 😅

Sorry, it is not very popular to fix (and I don’t know simple solution).

I will release fix to process().root and close the issue.

Unfortunately, it will be to big change for small use case.

Where exactly for you have a problem with result.root case? Maybe I can suggest a better way to handle it if you will provide me more context.

I added Result#root casting from process({ parser }) type 7d51976a

It will be Root if we didn’t pass parser option and will have Document type only if opts.parser types return Document.

By if we don’t know source of the Result ({ result } in plugin) it will continue to be Root | Document.

What do you think? Will it simplify PostCSS API for you?

Nope, we are planning to use Document and don’t plan many changes.