visual studio code - Typescript jsdoc med annotera parameter egenskap
Jag försöker annotera en egenskap hos ett objekt som är ett argument till en funktion.
Specifikt vill jag att options.length förklaring ska visas i VSCode när man hovrar över funktionsdefinitionen.
/**
* Memoize a function
* @param {(...fnArgs: T[]) => U} fn The function to memoize
* @param {Object} options Memoization options
* @param {number} options.max The max size of the LRU cache
* @param {number | undefined} options.length The response will be cached
* by the first N args, based on this value. Trailing args will still be
* passed to the underlying function but will be ignored during memoization.
*/
export const memo = <T, U>(
fn: (...fnArgs: T[]) => U,
{ max, length }: { max: number; length?: number }
) => {
const cachedArgs: T[][] = []
const cachedValues: U[] = []
const get = (args: T[]): U | undefined => {
const index = cachedArgs.findIndex(x => argsAreEqual(x, args, length))
if (index === -1) return
onUsed(index)
return cachedValues[index]
}
const set = (args: T[], value: U) => {
cachedArgs.push(args)
cachedValues.push(value)
}
const onUsed = (index: number) => {
moveToEnd(index, cachedArgs)
moveToEnd(index, cachedValues)
}
const prune = () => {
if (cachedArgs.length >= max) {
cachedArgs.shift()
cachedValues.shift()
}
}
return (...args: T[]) => {
let value = get(args)
if (value) return value
prune()
value = fn(...args)
set(args, value)
return value
}
}
När jag hovrar över typsignaturen får jag följande
@param fn — The function to memoize
@param options — Memoization options
Jag har gjort mitt bästa för att kopiera från dokumentationen men det visar inte förklaringen för options.length.
Jag vill att det ska visa förklaringen på hur options.length-parametern fungerar. Hur kan jag göra detta?
Bonusfråga, är inte säker på hur man får generics att fungera med jsdoc heller... hjälp med @template uppskattas mycket!
Svar #1
Detta beteende verkar vara en känd bugg, där destrukturerade parametrar inte har sina JSDoc-kommentarer visade: microsoft/TypeScript#24746. Jag är inte riktigt säker på varför, men enligt en kommentar är det att ge en @param typen Object ekvivalent med att ge den typen any, och du kan få det beteende du vill ha genom att använda en annan typ. Nedan ändrar jag Object till {}:
/**
* @param {(...fnArgs: T[]) => U} fn
* @param {{}} options Memoization options
* @param {number} options.max The max size of the LRU cache
* @param {number | undefined} options.length The response will be cached
* by the first N args, based on this value. Trailing args will still be
* passed to the underlying function but will be ignored during memoization.
*/
export const memo = <T, U>(
fn: (...fnArgs: T[]) => U,
{ max, length }: { max: number; length?: number }
) => { }
och din IntelliSense börjar fungera, åtminstone när du hovrar över funktionen. (Jag tror inte att det är möjligt att få kommentarer när du hovrar över själva identifieraren som heter max eller length i din kod). Observera:
/* IntelliSense shows:
const memo: <T, U>(fn: (...fnArgs: T[]) => U, { max, length }: {
max: number;
length?: number | undefined;
}) => void
@param fn
@param options — Memoization options
@param options.max — The max size of the LRU cache
@param options.length — The response will be cached by the first N args,
based on this value. Trailing args will still be passed to the
underlying function but will be ignored during memoization.
*/
OBS! Detta verkar endast fungera för TypeScript-kod (som .ts eller .tsx) och inte JavaScript-kod. Om du gör detta i JavaScript kommer kompilatorn att klaga på allt annat än Object eller object.
När det gäller din bonusfråga, tror jag att det borde fungera i TypeScript precis som det gör i JavaScript:
/**
* @template T the arg type of fn
* @template U the return type of fn
* @param {(...fnArgs: T[]) => U} fn
som visar mig
/* IntelliSense shows:
const memo: <T, U>(fn: (...fnArgs: T[]) => U, { max, length }: {
max: number;
length?: number | undefined;
}) => void
@template — T the arg type of fn
@template — U the return type of fn
@param fn
*/
Playground-länk till kod
