From b031ca897aa4d43d67656a0ddce699eb2a959112 Mon Sep 17 00:00:00 2001 From: firefoxic Date: Sun, 18 Oct 2026 15:38:50 +0300 Subject: [PATCH 1/2] Spell `Selector` without the self-reference its base type holds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The workaround of 2020 for #232 spells `Selector` as a type alias over an interface parameterized by itself, so that the base type of `Selector` is not `Selector` itself. The TypeScript 7.1 nightlies refuse to check that, with `TS5115` on every use of the type, reported where the type is used rather than in the declaration, so `skipLibCheck` passes over it and it reaches whoever instantiates `Selector`. Writing the self-reference back into the interface is `TS2310` again, which is what #232 was about, and every other spelling costs the same on some compiler: a `Selector` that says its children are the nodes that are not selectors has to name the node union in its own base type, and that union holds `Selector`. The exclusion is given up instead, so a selector's children are typed as any node. The parser never puts a selector inside a selector, and the type test narrows by `type` before reading, so nothing in this package relies on the exclusion — but it is a loosening, and a different trade may suit this package better than this one does. --- postcss-selector-parser.d.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/postcss-selector-parser.d.ts b/postcss-selector-parser.d.ts index 9f0a233..15ad1df 100644 --- a/postcss-selector-parser.d.ts +++ b/postcss-selector-parser.d.ts @@ -14,9 +14,6 @@ */ export = parser; -// A type that's T but not U. -type Diff = T extends U ? never : T; - // TODO: Conditional types in TS 1.8 will really clean this up. declare function parser(): parser.Processor; declare function parser(processor: parser.AsyncProcessor): parser.Processor; @@ -347,10 +344,9 @@ declare namespace parser { function root(opts: ContainerOptions): Root; function isRoot(node: any): node is Root; - interface _Selector extends Container> { + interface Selector extends Container { type: "selector"; } - type Selector = _Selector; function selector(opts: ContainerOptions): Selector; function isSelector(node: any): node is Selector; From 827622052dd875ddb6eb0fcf9f6fb92741fcd531 Mon Sep 17 00:00:00 2001 From: firefoxic Date: Mon, 9 Nov 2026 14:05:27 +0300 Subject: [PATCH 2/2] fix(types): preserve selector child exclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep selector children typed as every node except selectors without making the recursive node union part of Container’s base type. This preserves exhaustive narrowing while avoiding the TypeScript 7.1 recursion error. --- postcss-selector-parser.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/postcss-selector-parser.d.ts b/postcss-selector-parser.d.ts index 9ff4bdb..689ccfd 100644 --- a/postcss-selector-parser.d.ts +++ b/postcss-selector-parser.d.ts @@ -14,6 +14,9 @@ */ export = parser; +// A type that's T but not U. +type Diff = T extends U ? never : T; + // TODO: Conditional types in TS 1.8 will really clean this up. declare function parser(processor?: undefined, options?: Partial): parser.Processor; declare function parser(processor: parser.AsyncProcessor, options?: Partial): parser.Processor; @@ -352,6 +355,7 @@ declare namespace parser { interface Selector extends Container { type: "selector"; + nodes: Array>; } function selector(opts: ContainerOptions): Selector; function isSelector(node: any): node is Selector;