Repository navigation
fix: build and typecheck with postcss 8.5 - #1516
Merged
Merged
Conversation
The committed lockfile resolves postcss to 8.4.31, so the typings of 8.5 are never checked. The script swaps in the manifests and lockfile of the postcss 8.5.23 update, runs typecheck for @linaria/server, @linaria/postcss-linaria and @linaria/atomic, and puts everything back. It fails today: TS18048 for the unguarded AtRule nodes in packages/server/src/collect.ts and TS2322 for the raw and rawValue returns in packages/postcss-linaria/src/stringify.ts.
postcss 8.5 types `AtRule#nodes` as possibly undefined, so the typecheck of @linaria/server fails against it. `handleAtRule` only receives the parents of rules, which always have nodes, so reading them through optional chaining keeps the output unchanged on postcss 8.4 and 8.5.
postcss 8.5 widens the declared results of `Stringifier#raw` to `boolean | string` and of `Stringifier#rawValue` to `number | string`, while 8.4 declares `string` for both. The overrides return the base result unchanged and keep their `string` signatures, which the raws and fields the stringifier reads through them satisfy, so they compile against both versions without a runtime change.
`Stringifier#raw` does return a boolean at runtime: the inherited `body` reads the `semicolon` raw through it. The comments claimed that every raw read through the override is a string. Say instead that `string` is the declared signature the calls in this class rely on, and that the base result is returned unchanged. Comment-only, no code change.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The dependabot pull request #1504 raises postcss from 8.4.31 to 8.5.23 in
@linaria/atomic,@linaria/postcss-linariaand@linaria/server, and the build fails on it. postcss 8.5 changed three declarations that the sources relied on, and typechecking the three packages against 8.5.23 onmasterreports these errors:AtRule#nodesis typed as possibly undefined, so reading it without a check is TS18048 inpackages/server/src/collect.ts:otherRule.nodes[index - removedNodesFromOther]?.remove();if (criticalRule.nodes.length > 0) {if (otherRule.nodes.length > 0) {Stringifier#rawis declared asboolean | stringandStringifier#rawValueasnumber | string(8.4.31 declaresstringfor both), so the overrides inpackages/postcss-linaria/src/stringify.tsfail with TS2322 where they return the inherited result from methods declared asstring:return super.raw(node, own, detect);return super.rawValue(node, prop);This pull request fixes those errors in the sources so that #1504 can be rebased and merged. The package manifests keep
^8.4.31; the bump itself stays in #1504.Summary
The change touches two source files. No
package.json, lockfile, snapshot or test file is edited.packages/server/src/collect.ts:handleAtRulereads thenodesof the cloned at-rules through optional chaining:nodes?.[i]?.remove()andnodes?.length.handleAtRuleis only called with the parent of a walked rule, which always has nodes, so theundefinedbranch is unreachable and the output does not change.packages/postcss-linaria/src/stringify.ts: therawandrawValueoverrides keep theirstringsignatures and returnsuper.raw(...) as stringandsuper.rawValue(...) as string, with a comment saying why. The inherited result is returned unchanged.Why an assertion and not a guard in
stringify.ts:bodyreads the booleansemicolonraw through the override, so converting withString(...)turnsfalseinto the truthy'false'. I tried it on postcss 8.4.31 and 3 of the 100@linaria/postcss-linariatests failed.boolean | stringbreaks the class's own callers, which pass the result on asstring(TS2345 and TS2322 at several call sites in the same file).The class is not exported, and the assertions are erased at compile time.
Published output: with the committed lockfile (postcss 8.4.31), the emitted declarations of
@linaria/server,@linaria/postcss-linariaand@linaria/atomicare identical tomaster, so I did not add a changeset. The emitted JavaScript differs only by the null checks incollect.tsand by comments instringify.ts.The first commit adds
scripts/typecheck-postcss-8-5.sh. It is separate from the fix and can be dropped. It swaps in the manifests and lockfile of the postcss 8.5.23 update from the head of #1504, installs with--ignore-scripts, typechecks the three packages and puts the committed files back on exit. It needs the head commit of #1504 to be fetched in the clone and stops with a clear message otherwise. On themastersources it fails with the errors listed above, and with this fix it passes. If it is interrupted during its own install, a plainpnpm install --frozen-lockfileputsnode_modulesback. It stops being useful once postcss 8.5.23 is in the committed lockfile.Test plan
I ran these on the committed lockfile (postcss 8.4.31) and again with the manifests and lockfile of #1504 applied temporarily (postcss 8.5.23, not committed). Both installs used
--ignore-scripts, with pnpm 9.15.9 and Node 24.4.1.On both versions:
error TS;@linaria/postcss-linariapasses 5 suites and 100 tests;@linaria/atomic, passes 150 tests with 2 skipped and 279 snapshots;@linaria/serveris the part these runs do not cover. It has notestscript, sopnpm turbo run testin CI does not run it, and its jest suite already fails onmaster, independent of postcss:prettier.formatreturns a Promise under prettier 3, so 16 of the 20 tests comparePromise {}with the snapshot strings. I left that suite alone, because repairing it edits existing test lines. Instead I compared its output: a copy ofcollect.test.tsthat awaitsprettier.formatwrites 16 fresh snapshots, and they are byte-identical betweenmasterand this branch on postcss 8.4.31, betweenmasterand this branch on postcss 8.5.23, and between this branch on the two versions. Nothing else about@linaria/serveron 8.5.23 was run.