最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is the generic type of this class getting overwritten in JSDOC, but not Typescript? - Stack Overflow

programmeradmin0浏览0评论

We're working on converting a project from Typescript (.ts) to Typescript-via-JSDOC (.js).

We have a class StateHolder, instances of which contain data described by the generic State. The data can be provided at instantiation, or later on.

Here's a very minimal version of how it looks in Typescript, which passes type-checking and compiles without issue:

// state.ts

type StateHolderOptions = {};

class StateHolder<State> {
    value?: State;

    constructor(
        initialValue?: State,
        options: StateHolderOptions = {}
    ) {
        if (initialValue !== undefined) {
            this.value = initialValue;
        }
    }
}

type MyState = { data: string };

const state = new StateHolder<MyState>(undefined, {});

Here's the same code as we've converted it into JS:

// state.js

/**
 * @typedef {object} StateHolderOptions
 */

/**
 * @template State
 */
class StateHolder {
    /**
     * @type {State | undefined}
     */
    value;

    /**
     * @param {State} [initialValue]
     * @param {StateHolderOptions} [options] - Unused
     */
    constructor(initialValue, options = {}) {
        if (initialValue !== undefined) {
            this.value = initialValue;
        }
    }
}

/**
 * @typedef {{ data: string }} MyState
 */

const state = /** @type {StateHolder<MyState>} */(new StateHolder(undefined, {}));

We thought the JS and TS were exactly equivalent. However, in the JS version the final line const state throws this type-checking error:

Conversion of type 'StateHolder<undefined>' to type 'StateHolder<MyState>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'undefined' is not comparable to type 'MyState'.

We don't get type errors if we do this, but it's very verbose so would be nice to avoid it:

const state = new StateHolder(/** @type {MyState} */(/**  @type {unknown} */(undefined)), {});

We may be able to get the correct typing by defining it in types.d.ts but would rather do it in one file if we can.

Why do the JS and TS versions behave differently, and in JS how can we maintain the generic State while passing in undefined?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论