fix(45919): allow using JSDoc types for arrow function with type predicate (#45952)
This commit is contained in:
parent
e0f436c628
commit
d613748932
|
@ -23206,10 +23206,10 @@ namespace ts {
|
|||
return isLengthPushOrUnshift || isElementAssignment;
|
||||
}
|
||||
|
||||
function isDeclarationWithExplicitTypeAnnotation(declaration: Declaration) {
|
||||
return (declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter ||
|
||||
declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) &&
|
||||
!!getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature);
|
||||
function isDeclarationWithExplicitTypeAnnotation(node: Declaration) {
|
||||
return (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isParameter(node)) &&
|
||||
!!(getEffectiveTypeAnnotationNode(node) ||
|
||||
isInJSFile(node) && hasInitializer(node) && node.initializer && isFunctionExpressionOrArrowFunction(node.initializer) && getEffectiveReturnTypeNode(node.initializer));
|
||||
}
|
||||
|
||||
function getExplicitTypeOfSymbol(symbol: Symbol, diagnostic?: Diagnostic) {
|
||||
|
@ -26570,10 +26570,6 @@ namespace ts {
|
|||
return !hasEffectiveRestParameter(signature) && getParameterCount(signature) < targetParameterCount;
|
||||
}
|
||||
|
||||
function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
|
||||
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
|
||||
}
|
||||
|
||||
function getContextualSignatureForFunctionLikeDeclaration(node: FunctionLikeDeclaration): Signature | undefined {
|
||||
// Only function expressions, arrow functions, and object literal methods are contextually typed.
|
||||
return isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node)
|
||||
|
|
|
@ -7415,4 +7415,8 @@ namespace ts {
|
|||
const declaration = symbol.valueDeclaration && getRootDeclaration(symbol.valueDeclaration);
|
||||
return !!declaration && (isParameter(declaration) || isCatchClauseVariableDeclaration(declaration));
|
||||
}
|
||||
|
||||
export function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
|
||||
return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
|
||||
}
|
||||
}
|
||||
|
|
50
tests/baselines/reference/assertionTypePredicates2.js
Normal file
50
tests/baselines/reference/assertionTypePredicates2.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
//// [assertionTypePredicates2.js]
|
||||
/**
|
||||
* @typedef {{ x: number }} A
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef { A & { y: number } } B
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {A} a
|
||||
* @returns { asserts a is B }
|
||||
*/
|
||||
const foo = (a) => {
|
||||
if (/** @type { B } */ (a).y !== 0) throw TypeError();
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const main = () => {
|
||||
/** @type { A } */
|
||||
const a = { x: 1 };
|
||||
foo(a);
|
||||
};
|
||||
|
||||
|
||||
//// [assertionTypePredicates2.js]
|
||||
"use strict";
|
||||
/**
|
||||
* @typedef {{ x: number }} A
|
||||
*/
|
||||
exports.__esModule = true;
|
||||
exports.main = void 0;
|
||||
/**
|
||||
* @typedef { A & { y: number } } B
|
||||
*/
|
||||
/**
|
||||
* @param {A} a
|
||||
* @returns { asserts a is B }
|
||||
*/
|
||||
var foo = function (a) {
|
||||
if ( /** @type { B } */(a).y !== 0)
|
||||
throw TypeError();
|
||||
return undefined;
|
||||
};
|
||||
var main = function () {
|
||||
/** @type { A } */
|
||||
var a = { x: 1 };
|
||||
foo(a);
|
||||
};
|
||||
exports.main = main;
|
42
tests/baselines/reference/assertionTypePredicates2.symbols
Normal file
42
tests/baselines/reference/assertionTypePredicates2.symbols
Normal file
|
@ -0,0 +1,42 @@
|
|||
=== tests/cases/conformance/controlFlow/assertionTypePredicates2.js ===
|
||||
/**
|
||||
* @typedef {{ x: number }} A
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef { A & { y: number } } B
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {A} a
|
||||
* @returns { asserts a is B }
|
||||
*/
|
||||
const foo = (a) => {
|
||||
>foo : Symbol(foo, Decl(assertionTypePredicates2.js, 12, 5))
|
||||
>a : Symbol(a, Decl(assertionTypePredicates2.js, 12, 13))
|
||||
|
||||
if (/** @type { B } */ (a).y !== 0) throw TypeError();
|
||||
>(a).y : Symbol(y, Decl(assertionTypePredicates2.js, 5, 19))
|
||||
>a : Symbol(a, Decl(assertionTypePredicates2.js, 12, 13))
|
||||
>y : Symbol(y, Decl(assertionTypePredicates2.js, 5, 19))
|
||||
>TypeError : Symbol(TypeError, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
return undefined;
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
};
|
||||
|
||||
export const main = () => {
|
||||
>main : Symbol(main, Decl(assertionTypePredicates2.js, 17, 12))
|
||||
|
||||
/** @type { A } */
|
||||
const a = { x: 1 };
|
||||
>a : Symbol(a, Decl(assertionTypePredicates2.js, 19, 9))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates2.js, 19, 15))
|
||||
|
||||
foo(a);
|
||||
>foo : Symbol(foo, Decl(assertionTypePredicates2.js, 12, 5))
|
||||
>a : Symbol(a, Decl(assertionTypePredicates2.js, 19, 9))
|
||||
|
||||
};
|
||||
|
51
tests/baselines/reference/assertionTypePredicates2.types
Normal file
51
tests/baselines/reference/assertionTypePredicates2.types
Normal file
|
@ -0,0 +1,51 @@
|
|||
=== tests/cases/conformance/controlFlow/assertionTypePredicates2.js ===
|
||||
/**
|
||||
* @typedef {{ x: number }} A
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef { A & { y: number } } B
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {A} a
|
||||
* @returns { asserts a is B }
|
||||
*/
|
||||
const foo = (a) => {
|
||||
>foo : (a: A) => asserts a is B
|
||||
>(a) => { if (/** @type { B } */ (a).y !== 0) throw TypeError(); return undefined;} : (a: A) => asserts a is B
|
||||
>a : A
|
||||
|
||||
if (/** @type { B } */ (a).y !== 0) throw TypeError();
|
||||
>(a).y !== 0 : boolean
|
||||
>(a).y : number
|
||||
>(a) : B
|
||||
>a : A
|
||||
>y : number
|
||||
>0 : 0
|
||||
>TypeError() : TypeError
|
||||
>TypeError : TypeErrorConstructor
|
||||
|
||||
return undefined;
|
||||
>undefined : undefined
|
||||
|
||||
};
|
||||
|
||||
export const main = () => {
|
||||
>main : () => void
|
||||
>() => { /** @type { A } */ const a = { x: 1 }; foo(a);} : () => void
|
||||
|
||||
/** @type { A } */
|
||||
const a = { x: 1 };
|
||||
>a : A
|
||||
>{ x: 1 } : { x: number; }
|
||||
>x : number
|
||||
>1 : 1
|
||||
|
||||
foo(a);
|
||||
>foo(a) : void
|
||||
>foo : (a: A) => asserts a is B
|
||||
>a : A
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @outDir: ./out
|
||||
// @filename: assertionTypePredicates2.js
|
||||
|
||||
/**
|
||||
* @typedef {{ x: number }} A
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef { A & { y: number } } B
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {A} a
|
||||
* @returns { asserts a is B }
|
||||
*/
|
||||
const foo = (a) => {
|
||||
if (/** @type { B } */ (a).y !== 0) throw TypeError();
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const main = () => {
|
||||
/** @type { A } */
|
||||
const a = { x: 1 };
|
||||
foo(a);
|
||||
};
|
Loading…
Reference in a new issue