* Support the JSDoc @enum tag `@enum` is used on a variable declaration with an object literal initializer. It does a number of things: 1. The object literal has a closed set of properties, unlike other object literals in Javascript. 2. The variable's name is resolvable as a type, but it just has the declared type of the enum tag. 3. Each property's type must be assignable to the enum tag's declared type, which can be any type. For example, ```js /** @enum {string} */ const Target = { START: "START", END: "END", MISTAKE: 0, // error 'number' is not assignable to 'string' -- see (3) } Target.THIS_IS_AN_ERROR; // See (1) /** @type {Target} See (2) */ var target = Target.START; ``` * Fix lint, add new test case, update API baselines
56 lines
1.1 KiB
TypeScript
56 lines
1.1 KiB
TypeScript
// @allowJs: true
|
|
// @checkJs: true
|
|
// @noEmit: true
|
|
// @Filename: a.js
|
|
/** @enum {string} */
|
|
const Target = {
|
|
START: "start",
|
|
MIDDLE: "middle",
|
|
END: "end",
|
|
MISTAKE: 1,
|
|
/** @type {number} */
|
|
OK_I_GUESS: 2
|
|
}
|
|
/** @enum {number} */
|
|
const Second = {
|
|
MISTAKE: "end",
|
|
OK: 1,
|
|
/** @type {number} */
|
|
FINE: 2,
|
|
}
|
|
/** @enum {function(number): number} */
|
|
const Fs = {
|
|
ADD1: n => n + 1,
|
|
ID: n => n,
|
|
SUB1: n => n - 1
|
|
}
|
|
|
|
/** @param {Target} t
|
|
* @param {Second} s
|
|
* @param {Fs} f
|
|
*/
|
|
function consume(t,s,f) {
|
|
/** @type {string} */
|
|
var str = t
|
|
/** @type {number} */
|
|
var num = s
|
|
/** @type {(n: number) => number} */
|
|
var fun = f
|
|
/** @type {Target} */
|
|
var v = Target.START
|
|
v = Target.UNKNOWN // error, can't find 'UNKNOWN'
|
|
v = Second.MISTAKE // meh..ok, I guess?
|
|
v = 'something else' // allowed, like Typescript's classic enums and unlike its string enums
|
|
}
|
|
/** @param {string} s */
|
|
function ff(s) {
|
|
// element access with arbitrary string is an error only with noImplicitAny
|
|
if (!Target[s]) {
|
|
return null
|
|
}
|
|
else {
|
|
return Target[s]
|
|
}
|
|
}
|
|
|
|
|