Skip to content

Returned types on some functions are wrong #67

@ankhzet

Description

@ankhzet

Whenever a function returns synthetic enum, f.e. Line.direction:

// line.js

	/**
	 * @property direction - The line direction
	 * @returns {Line.Direction} - either input (1) or output (2)
	 */
	get direction() {
		return libgpiod.getLineDirection(this._handler);
	}

when the library is built and type definitions are generated, the return values become objects.

// line.d.ts

    /**
     * @property direction - The line direction
     * @returns {Line.Direction} - either input (1) or output (2)
     */
    get direction(): {
        INPUT: number;
        OUTPUT: number;
    };

The reason is that corresponding (returned) types are declared as objects, not proper enums or const objects:

export class Line {
    ...
    static Direction: { // <- this is an OBJECT, not an ENUM
        INPUT: number;
        OUTPUT: number;
    };

Possible solutions:

  1. use proper typescript, not js+jsdoc
  2. potentially, this might work:
/**
 * @template {object} O
 * @typedef {O[keyof O]} Values
 */

class Line {
    /**
     * @property direction - The line direction
     * @returns {Values<typeof Line.Direction>} - either input (1) or output (2)
     */
    get direction() { ... }

P.S. const objects as enums are usually declared as such:

const Direction = {
    INPUT: 1,
    OUTPUT: 2,
} as const;
type Direction = (typeof Direction)[keyof typeof Direction];

class Line {
    static Direction = Direction;
}

type Values<O extends object> = O[keyof O];

const a: Direction = 1;
const b: Direction = Direction.INPUT;
const c: Direction = Line.Direction.INPUT;

const d: Line.Direction = ...; // this would not work
const e: Values<typeof Line.Direction> = ...; // this would

The Line.-adressable const enum maddness in pure typescript couldn't be implemented without workarounds either:

// enums.ts

export enum _Direction {
    INPUT = 1,
    OUTPUT = 2,
}

export const Direction = _Direction;
export type Direction = _Direction;

// line.ts
import { Direction } from './enum';

class Line {
    static Direction = Direction;

    get direction(): Direction {
        return Direction.INPUT;
    }
}

// to support `const c: Line.Direction = `

namespace Line {
    export declare type Direction = _Direction; // add _Direction import for this to work
}

// test.ts
import { Direction } from './enum';
import { Line } from './line';

const a: Direction = 1;
const b: Direction = Direction.INPUT;
const c: Line.Direction = Line.Direction.INPUT;

const l = new Line();
const direction = l.direction;
const isInput = direction === Line.Direction.INPUT;

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggpiod-1.xall related to underlying libgpiod-1.x series

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions