class Entry {
constructor() {
this.c = 1
}
/**
* @param {any} x
* @return {this is Entry}
*/
isInit(x) {
return true
}
}
class Group {
constructor() {
this.d = 'no'
}
/**
* @param {any} x
* @return {false}
*/
isInit(x) {
return false
}
}
/** @param {Entry | Group} chunk */
function f(chunk) {
let x = chunk.isInit(chunk) ? chunk.c : chunk.d
return x
}
Expected behavior:
Should be equivalent to
declare class C {
c: number
isInit(x: any): this is C
}
declare class D {
d: string
isInit(x: any): false
}
function f (g: C | D) {
let x = g.isInit(g) ? g.c : g.d
}
And narrow upon calling isInit.
Actual behavior:
No narrowing, and Entry.isInit's return type is just boolean.
On TypeScript 3.0rc I cannot guard function parameters:
/**
* @param {any} options
* @return {options is MyOptions}
*/
function isMyOptions(options) {
return true;
}
Cannot find name 'options'.
Based on the above, you should write:
- * @return {options is MyOptions}
+ * @return {this is MyOptions}
Assert this even though I'm not typing a class like the OP, but a function parameter? I've attempted what you suggested, but JSDoc TypeScript does not change the options value from its original type after checking it with the guard, as happens in ordinary TypeScript files.
/**
* @param {RequestOptions} options
* @return {this is MyOptions}
*/
function isMyOptions(options) {
return true // would normally check options.type
}
/**
* @param {MyOptions} options
*/
function takesMyOptions(options) {
console.log(options.specialField);
}
/**
* @param {Request<RequestOptions>} request
*/
function doWork(request) {
const options = request.options; // type RequestOptions
if (!isMyOptions(options)) throw new Error('Request was not of type MyOptions');
takesMyOptions(options); // Still type RequestOptions, TypeScript error
}
@spiffytech try using any for the type of options in isMyOptions, and replace the this with options in the return type.
For anyone Googling, this has been fixed by #26297. Use the name of the argument in the is clause (not this). Here is the correct syntax:
// @ts-check
/**
* @param {any} value
* @return {value is boolean}
*/
function isBoolean(value) {
return typeof value === "boolean";
}
Most helpful comment
For anyone Googling, this has been fixed by #26297. Use the name of the argument in the
isclause (notthis). Here is the correct syntax: