我正在尝试使用 JSDoc 来记录我的反应状态挂钩的解构部分,例如:
const [referenceState, setReferenceState] = useState(null);
这里,
referenceState
是对象类型,setReferenceState
需要一个对象。
根据网上的一些信息,我正在尝试做以下事情:
/**
* @param {Object} stateToSet
* @returns {GenericArray} current state and function to change value
*/
const [referenceState, setReferenceState] = useState(null);
但这不会产生任何东西..
有人可以帮我记录
referenceState
和 setReferenceState
吗?
在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)
更新: 似乎最易读的简短解决方案是使用 ReturnType
/**
* @type {ReturnType<typeof useState<number>>}
*/
const [num, setNum] = useState(null);
最短的方法是这样:通过添加模板
/**
* @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);
我认为你可以尝试这种方法:
/**
* @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
)——如果这就是 setter 返回的内容。有些项目如果只返回 @returns
,就会删除 undefined
,但我喜欢添加它以显示已知返回值是 undefined
,而不仅仅是未记录。
我将创建一个与 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);
作为替代方案,可以在解构之前声明变量并像平常一样使用 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);
给
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));