如何使用JSDoc记录useState hooks?

17

我正在尝试使用 JSDoc 来记录我的 React 状态钩子(state hooks)的解构部分,例如:

const [referenceState, setReferenceState] = useState(null);

这里,referenceState 是一个对象类型,而 setReferenceState 期望一个对象。

根据一些在线信息,我正在尝试做一些类似以下的事情:

/**
* @param {Object} stateToSet
* @returns {GenericArray} current state and function to change value
*/
const [referenceState, setReferenceState] = useState(null);

但是那样并没有产生任何东西..

有人能帮我记录referenceStatesetReferenceState吗?


referenceState是什么类型?是一个对象吗?setReferenceState需要哪些参数并返回什么? - Brett Zamir
@BrettZamir 抱歉我没有添加那些细节。我已经编辑了问题。你是对的,referenceState 是一个对象,而 setReferenceState 期望一个对象。 - theabhinavdas
6个回答

8

在WebStorm中,您可以像这样编写代码(我还没有在其他编辑器中进行测试):

const [state, setState] = useState(/** @type {{name: string, age: number?}} */null)

或者
/**
 * @typedef People
 * @property {string} name
 * @property {number} [age]
 */

//........

const [state, setState] = useState(/** @type {People} */null)


1
这在 vscode 中也可以工作。 - gianlucaparadise
2
在VS Code中,你需要在null周围加上括号。 const [state, setState] = useState(/** @type {People} */(null)) - Max

7
最简单的方法是:通过添加一个模板。
/**
 * @type {[MyType, React.Dispatch<MyType>]} state
 */
const [value, setValue] = useState(null);

我也在JS项目中使用*.d.ts文件。VS Code可以识别并使用它们,因此您可以以现代方式描述类型和接口。
只需添加一行即可:
type useState<T> = [T, React.Dispatch<T>];

将useState.d.ts文件添加到您的项目中,然后在JS文件中使用它。

/** @type {useState<MyType>} */
const [value, setValue] = useState(null);

由于某种原因,我上面写的类型转换只能与useState(null)一起正常工作。如果您提供了一些不错的初始状态值,那么这个值类型会重载转换后的类型.. 更有趣的是...在useState行中,VS代码仍然显示转换后的类型,但下面的值具有useState内部值的类型。 在useState()内提供类型的解决方案更加健壮。尽管它看起来要糟糕得多,但有时我还是会使用它。 - zamuka

5

我认为你可以尝试这种方法:

/**
 * @typedef {Object} ReferenceState
 */

/**
 * @callback ReferenceStateSetter
 * @param {ReferenceState} state
 * @returns {void}
 */

/**
 * @namespace {Object}
 * @property {ReferenceState} 0
 * @property {ReferenceStateSetter} 1 
 */
const [referenceState, setReferenceState] = useState(null);

或者,为了避免必须记录立即解构的数组,但又想在最后添加一些缩进更改:

/**
 * @typedef {Object} ReferenceState
 */

/**
 * @callback ReferenceStateSetter
 * @param {ReferenceState} state
 * @returns {void}
 */

const [
    /**
     * @type {ReferenceState}
     */
    referenceState,

    /**
     * @type {ReferenceStateSetter}
     */
    setReferenceState
] = useState(null);

如果您不想为 "ReferenceState" 准备文档,您可以摆脱它的 "@typedef" 并将对它的引用替换为 "Object",但我认为有文档会更清晰。
上面的 "void" 是一种更简单的方式表达没有特殊返回值(即 "undefined") - 如果这是设置器返回的内容。一些项目可能只会丢弃 "@returns",如果它只返回 "undefined",但我喜欢添加它以显示返回值已知为 "undefined",而不仅仅是未记录。

2
我会创建一个通用类型,该类型等于React的useState函数返回的相同类型。
/**
 * Add this type in top of your file, or if commonly used in some types file.
 * @template T
 * @typedef {[T, import('react').Dispatch<import('react').SetStateAction<T>>]} useState
 */

然后你可以在React组件中像这样使用它:
/** @type {useState<string>} */
const [someString, setSomeString] = useState('');

/** @type {useState<number>} */
const [someNumber, setSomeNumber] = useState(2);

或者您想使用自定义对象:

/**
 * @typedef SomeOtherType
 * @property {string} property1
 * @property {number} property2
 */

/** @type {useState<SomeOtherType>} */
const [someOtherValue, setSomeOtherValue] = useState(null);

0
作为一种替代方案,变量可以在解构之前声明,并像正常情况下一样用JSDoc进行注释。
/**
* Current state.
* @type {Object}
*/
let referenceState;
/**
* Current state setter.
* @type {Function}
* @param {any} state updated state value.
* @returns void
*/
let setReferenceState;
[referenceState, setReferenceState] = useState(null);

0

useState(value) 中给初始值加上类型。

@types/react 中包含的 TypeScript 类型将用于推断解构数组值的类型。如果您正在使用 Create React App (react-scripts),那么您应该已经安装了 @types/react。否则,它可以作为 devDependency 安装。

请注意 null 周围的括号,这将有助于使用 VSCode,在其中使用 TypeScript 检查 JSDoc 类型。请参见 如何使用 JSDoc 在 javascript 中转换 TypeScript 类型

字符串示例

const [name, setName] = useState(/** @type {string?} */ (null));

对象示例

/**
 * @typedef {{ name: string, age: number}} Person
 */

const [people, setPeople] = useState(/** @type {Person[]?} */ (null));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接