Skip to content

Commit daebab0

Browse files
nex3jonathantneal
authored andcommitted
Improve typescript typings
* Add an additional parameter to Container to clarify that Root can only contain Selectors as immediate children and Selector cannot contain Selectors as immediate children. * Use polymorphic `this` types for Container methods that return the same object. * Narrow the type for Container.walk*() to indicate that only nodes of the given type will be passed to the callback. * Fix the type of Container.reduce() to match the type of Iterable.reduce().
1 parent 56156f7 commit daebab0

File tree

1 file changed

+79
-32
lines changed

1 file changed

+79
-32
lines changed

postcss-selector-parser.d.ts

+79-32
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
*/
1515
export = parser;
1616

17+
// A type that's T but not U.
18+
type Diff<T, U> = T extends U ? never : T;
19+
1720
// TODO: Conditional types in TS 1.8 will really clean this up.
1821
declare function parser(): parser.Processor<never>;
1922
declare function parser<Transform>(processor: parser.AsyncProcessor<Transform>): parser.Processor<Transform, never>;
@@ -203,11 +206,14 @@ declare namespace parser {
203206
interface ContainerOptions extends NodeOptions {
204207
nodes?: Array<Node>;
205208
}
206-
interface Container<Value extends string | undefined = string> extends Base<Value> {
207-
nodes: Array<Node>;
208-
append(selector: Selector): Container;
209-
prepend(selector: Selector): Container;
210-
at(index: number): Node;
209+
interface Container<
210+
Value extends string | undefined = string,
211+
Child extends Node = Node
212+
> extends Base<Value> {
213+
nodes: Array<Child>;
214+
append(selector: Selector): this;
215+
prepend(selector: Selector): this;
216+
at(index: number): Child;
211217
/**
212218
* Return the most specific node at the line and column number given.
213219
* The source location is based on the original parsed location, locations aren't
@@ -221,33 +227,74 @@ declare namespace parser {
221227
* @param line The line number of the node to find. (1-based index)
222228
* @param col The column number of the node to find. (1-based index)
223229
*/
224-
atPosition(line: number, column: number): Node;
225-
index(child: Node): number;
226-
readonly first: Node;
227-
readonly last: Node;
230+
atPosition(line: number, column: number): Child;
231+
index(child: Child): number;
232+
readonly first: Child;
233+
readonly last: Child;
228234
readonly length: number;
229-
removeChild(child: Node): Container;
235+
removeChild(child: Child): this;
230236
removeAll(): Container;
231237
empty(): Container;
232-
insertAfter(oldNode: Node, newNode: Node): Container;
233-
insertBefore(oldNode: Node, newNode: Node): Container;
234-
each(callback: (node: Node) => boolean | void): boolean | undefined;
235-
walk(callback: (node: Node) => boolean | void): boolean | undefined;
236-
walkAttributes(callback: (node: Node) => boolean | void): boolean | undefined;
237-
walkClasses(callback: (node: Node) => boolean | void): boolean | undefined;
238-
walkCombinators(callback: (node: Node) => boolean | void): boolean | undefined;
239-
walkComments(callback: (node: Node) => boolean | void): boolean | undefined;
240-
walkIds(callback: (node: Node) => boolean | void): boolean | undefined;
241-
walkNesting(callback: (node: Node) => boolean | void): boolean | undefined;
242-
walkPseudos(callback: (node: Node) => boolean | void): boolean | undefined;
243-
walkTags(callback: (node: Node) => boolean | void): boolean | undefined;
244-
split(callback: (node: Node) => boolean): [Node[], Node[]];
245-
map(callback: (node: Node) => Node): Node[];
246-
reduce<T>(callback: (node: Node) => Node, memo: T): T;
247-
every(callback: (node: Node) => boolean): boolean;
248-
some(callback: (node: Node) => boolean): boolean;
249-
filter(callback: (node: Node) => boolean): Node[];
250-
sort(callback: (nodeA: Node, nodeB: Node) => number): Node[];
238+
insertAfter(oldNode: Child, newNode: Child): this;
239+
insertBefore(oldNode: Child, newNode: Child): this;
240+
each(callback: (node: Child) => boolean | void): boolean | undefined;
241+
walk(
242+
callback: (node: Node) => boolean | void
243+
): boolean | undefined;
244+
walkAttributes(
245+
callback: (node: Attribute) => boolean | void
246+
): boolean | undefined;
247+
walkClasses(
248+
callback: (node: ClassName) => boolean | void
249+
): boolean | undefined;
250+
walkCombinators(
251+
callback: (node: Combinator) => boolean | void
252+
): boolean | undefined;
253+
walkComments(
254+
callback: (node: Comment) => boolean | void
255+
): boolean | undefined;
256+
walkIds(
257+
callback: (node: Identifier) => boolean | void
258+
): boolean | undefined;
259+
walkNesting(
260+
callback: (node: Nesting) => boolean | void
261+
): boolean | undefined;
262+
walkPseudos(
263+
callback: (node: Pseudo) => boolean | void
264+
): boolean | undefined;
265+
walkTags(callback: (node: Tag) => boolean | void): boolean | undefined;
266+
split(callback: (node: Child) => boolean): [Child[], Child[]];
267+
map<T>(callback: (node: Child) => T): T[];
268+
reduce(
269+
callback: (
270+
previousValue: Child,
271+
currentValue: Child,
272+
currentIndex: number,
273+
array: readonly Child[]
274+
) => Child
275+
): Child;
276+
reduce(
277+
callback: (
278+
previousValue: Child,
279+
currentValue: Child,
280+
currentIndex: number,
281+
array: readonly Child[]
282+
) => Child,
283+
initialValue: Child
284+
): Child;
285+
reduce<T>(
286+
callback: (
287+
previousValue: T,
288+
currentValue: Child,
289+
currentIndex: number,
290+
array: readonly Child[]
291+
) => T,
292+
initialValue: T
293+
): T;
294+
every(callback: (node: Child) => boolean): boolean;
295+
some(callback: (node: Child) => boolean): boolean;
296+
filter(callback: (node: Child) => boolean): Child[];
297+
sort(callback: (nodeA: Child, nodeB: Child) => number): Child[];
251298
toString(): string;
252299
}
253300
function isContainer(node: any): node is Root | Selector | Pseudo;
@@ -273,7 +320,7 @@ declare namespace parser {
273320
}
274321
function isNamespace(node: any): node is Attribute | Tag;
275322

276-
interface Root extends Container<undefined> {
323+
interface Root extends Container<undefined, Selector> {
277324
type: "root";
278325
/**
279326
* Raises an error, if the processor is invoked on
@@ -285,7 +332,7 @@ declare namespace parser {
285332
function root(opts: ContainerOptions): Root;
286333
function isRoot(node: any): node is Root;
287334

288-
interface Selector extends Container {
335+
interface Selector extends Container<string, Diff<Node, Selector>> {
289336
type: "selector";
290337
}
291338
function selector(opts: ContainerOptions): Selector;
@@ -439,7 +486,7 @@ declare namespace parser {
439486
function attribute(opts: AttributeOptions): Attribute;
440487
function isAttribute(node: any): node is Attribute;
441488

442-
interface Pseudo extends Container {
489+
interface Pseudo extends Container<string, Selector> {
443490
type: "pseudo";
444491
}
445492
function pseudo(opts: ContainerOptions): Pseudo;

0 commit comments

Comments
 (0)