Fix `getEffectiveCheckNode` (#60309)
This commit is contained in:
Родитель
60dd512a83
Коммит
8d95ac5968
|
@ -726,7 +726,6 @@ import {
|
|||
isRightSideOfQualifiedNameOrPropertyAccess,
|
||||
isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName,
|
||||
isSameEntityName,
|
||||
isSatisfiesExpression,
|
||||
isSetAccessor,
|
||||
isSetAccessorDeclaration,
|
||||
isShorthandAmbientModuleSymbol,
|
||||
|
@ -35356,8 +35355,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
|||
}
|
||||
|
||||
function getEffectiveCheckNode(argument: Expression): Expression {
|
||||
argument = skipParentheses(argument);
|
||||
return isSatisfiesExpression(argument) ? skipParentheses(argument.expression) : argument;
|
||||
const flags = isInJSFile(argument)
|
||||
? OuterExpressionKinds.Parentheses | OuterExpressionKinds.Satisfies | OuterExpressionKinds.ExcludeJSDocTypeAssertion
|
||||
: OuterExpressionKinds.Parentheses | OuterExpressionKinds.Satisfies;
|
||||
return skipOuterExpressions(argument, flags);
|
||||
}
|
||||
|
||||
function getSignatureApplicabilityError(
|
||||
|
|
|
@ -637,8 +637,9 @@ export function isOuterExpression(node: Node, kinds: OuterExpressionKinds = Oute
|
|||
return (kinds & OuterExpressionKinds.Parentheses) !== 0;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.SatisfiesExpression:
|
||||
return (kinds & OuterExpressionKinds.TypeAssertions) !== 0;
|
||||
case SyntaxKind.SatisfiesExpression:
|
||||
return (kinds & (OuterExpressionKinds.TypeAssertions | OuterExpressionKinds.Satisfies)) !== 0;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return (kinds & OuterExpressionKinds.ExpressionsWithTypeArguments) !== 0;
|
||||
case SyntaxKind.NonNullExpression:
|
||||
|
|
|
@ -8557,8 +8557,9 @@ export const enum OuterExpressionKinds {
|
|||
NonNullAssertions = 1 << 2,
|
||||
PartiallyEmittedExpressions = 1 << 3,
|
||||
ExpressionsWithTypeArguments = 1 << 4,
|
||||
Satisfies = 1 << 5,
|
||||
|
||||
Assertions = TypeAssertions | NonNullAssertions,
|
||||
Assertions = TypeAssertions | NonNullAssertions | Satisfies,
|
||||
All = Parentheses | Assertions | PartiallyEmittedExpressions | ExpressionsWithTypeArguments,
|
||||
|
||||
ExcludeJSDocTypeAssertion = 1 << 31,
|
||||
|
|
|
@ -7434,8 +7434,9 @@ declare namespace ts {
|
|||
NonNullAssertions = 4,
|
||||
PartiallyEmittedExpressions = 8,
|
||||
ExpressionsWithTypeArguments = 16,
|
||||
Assertions = 6,
|
||||
All = 31,
|
||||
Satisfies = 32,
|
||||
Assertions = 38,
|
||||
All = 63,
|
||||
ExcludeJSDocTypeAssertion = -2147483648,
|
||||
}
|
||||
type ImmediatelyInvokedFunctionExpression = CallExpression & {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
mytest.js(6,44): error TS2322: Type 'string' is not assignable to type 'T'.
|
||||
'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.
|
||||
mytest.js(13,44): error TS2322: Type 'string' is not assignable to type 'T'.
|
||||
'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.
|
||||
|
||||
|
||||
==== mytest.js (2 errors) ====
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo1 = value => /** @type {string} */({ ...value });
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'T'.
|
||||
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo2 = value => /** @type {string} */(/** @type {T} */({ ...value }));
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'T'.
|
||||
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.
|
|
@ -0,0 +1,23 @@
|
|||
//// [tests/cases/compiler/arrowExpressionBodyJSDoc.ts] ////
|
||||
|
||||
=== mytest.js ===
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo1 = value => /** @type {string} */({ ...value });
|
||||
>foo1 : Symbol(foo1, Decl(mytest.js, 5, 5))
|
||||
>value : Symbol(value, Decl(mytest.js, 5, 12))
|
||||
>value : Symbol(value, Decl(mytest.js, 5, 12))
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo2 = value => /** @type {string} */(/** @type {T} */({ ...value }));
|
||||
>foo2 : Symbol(foo2, Decl(mytest.js, 12, 5))
|
||||
>value : Symbol(value, Decl(mytest.js, 12, 12))
|
||||
>value : Symbol(value, Decl(mytest.js, 12, 12))
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
//// [tests/cases/compiler/arrowExpressionBodyJSDoc.ts] ////
|
||||
|
||||
=== mytest.js ===
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo1 = value => /** @type {string} */({ ...value });
|
||||
>foo1 : <T>(value: T | undefined) => T
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>value => /** @type {string} */({ ...value }) : <T>(value: T | undefined) => T
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>value : T | undefined
|
||||
> : ^^^^^^^^^^^^^
|
||||
>({ ...value }) : string
|
||||
> : ^^^^^^
|
||||
>{ ...value } : {}
|
||||
> : ^^
|
||||
>value : T | undefined
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo2 = value => /** @type {string} */(/** @type {T} */({ ...value }));
|
||||
>foo2 : <T>(value: T | undefined) => T
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>value => /** @type {string} */(/** @type {T} */({ ...value })) : <T>(value: T | undefined) => T
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>value : T | undefined
|
||||
> : ^^^^^^^^^^^^^
|
||||
>(/** @type {T} */({ ...value })) : string
|
||||
> : ^^^^^^
|
||||
>({ ...value }) : T
|
||||
> : ^
|
||||
>{ ...value } : {}
|
||||
> : ^^
|
||||
>value : T | undefined
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
|
@ -31,9 +31,11 @@ typeSatisfaction_errorLocations1.ts(47,24): error TS2322: Type 'number' is not a
|
|||
typeSatisfaction_errorLocations1.ts(48,21): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'number' is not assignable to type 'true'.
|
||||
typeSatisfaction_errorLocations1.ts(50,23): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'.
|
||||
typeSatisfaction_errorLocations1.ts(51,24): error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'.
|
||||
|
||||
|
||||
==== typeSatisfaction_errorLocations1.ts (22 errors) ====
|
||||
==== typeSatisfaction_errorLocations1.ts (24 errors) ====
|
||||
const obj1 = { a: 1 };
|
||||
|
||||
const fn1 = (s: { a: true }) => {};
|
||||
|
@ -143,4 +145,13 @@ typeSatisfaction_errorLocations1.ts(48,21): error TS2322: Type '{ a: number; }'
|
|||
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: true; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'true'.
|
||||
|
||||
((): { a: true } => (({}) satisfies unknown) satisfies unknown)();
|
||||
~~
|
||||
!!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'.
|
||||
!!! related TS2728 typeSatisfaction_errorLocations1.ts:50:8: 'a' is declared here.
|
||||
((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)();
|
||||
~~
|
||||
!!! error TS2741: Property 'a' is missing in type '{}' but required in type '{ a: true; }'.
|
||||
!!! related TS2728 typeSatisfaction_errorLocations1.ts:51:8: 'a' is declared here.
|
||||
|
|
@ -129,3 +129,9 @@ function fn6(): number {
|
|||
>a : Symbol(a, Decl(typeSatisfaction_errorLocations1.ts, 47, 6))
|
||||
>obj1 : Symbol(obj1, Decl(typeSatisfaction_errorLocations1.ts, 0, 5))
|
||||
|
||||
((): { a: true } => (({}) satisfies unknown) satisfies unknown)();
|
||||
>a : Symbol(a, Decl(typeSatisfaction_errorLocations1.ts, 49, 6))
|
||||
|
||||
((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)();
|
||||
>a : Symbol(a, Decl(typeSatisfaction_errorLocations1.ts, 50, 6))
|
||||
|
||||
|
|
|
@ -384,3 +384,49 @@ function fn6(): number {
|
|||
>obj1 : { a: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
|
||||
((): { a: true } => (({}) satisfies unknown) satisfies unknown)();
|
||||
>((): { a: true } => (({}) satisfies unknown) satisfies unknown)() : { a: true; }
|
||||
> : ^^^^^ ^^^
|
||||
>((): { a: true } => (({}) satisfies unknown) satisfies unknown) : () => { a: true; }
|
||||
> : ^^^^^^
|
||||
>(): { a: true } => (({}) satisfies unknown) satisfies unknown : () => { a: true; }
|
||||
> : ^^^^^^
|
||||
>a : true
|
||||
> : ^^^^
|
||||
>true : true
|
||||
> : ^^^^
|
||||
>(({}) satisfies unknown) satisfies unknown : {}
|
||||
> : ^^
|
||||
>(({}) satisfies unknown) : {}
|
||||
> : ^^
|
||||
>({}) satisfies unknown : {}
|
||||
> : ^^
|
||||
>({}) : {}
|
||||
> : ^^
|
||||
>{} : {}
|
||||
> : ^^
|
||||
|
||||
((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)();
|
||||
>((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)() : { a: true; }
|
||||
> : ^^^^^ ^^^
|
||||
>((): { a: true } => ((({}) satisfies unknown)) satisfies unknown) : () => { a: true; }
|
||||
> : ^^^^^^
|
||||
>(): { a: true } => ((({}) satisfies unknown)) satisfies unknown : () => { a: true; }
|
||||
> : ^^^^^^
|
||||
>a : true
|
||||
> : ^^^^
|
||||
>true : true
|
||||
> : ^^^^
|
||||
>((({}) satisfies unknown)) satisfies unknown : {}
|
||||
> : ^^
|
||||
>((({}) satisfies unknown)) : {}
|
||||
> : ^^
|
||||
>(({}) satisfies unknown) : {}
|
||||
> : ^^
|
||||
>({}) satisfies unknown : {}
|
||||
> : ^^
|
||||
>({}) : {}
|
||||
> : ^^
|
||||
>{} : {}
|
||||
> : ^^
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// @strict: true
|
||||
// @noEmit: true
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
|
||||
// @filename: mytest.js
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo1 = value => /** @type {string} */({ ...value });
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T|undefined} value value or not
|
||||
* @returns {T} result value
|
||||
*/
|
||||
const foo2 = value => /** @type {string} */(/** @type {T} */({ ...value }));
|
|
@ -49,3 +49,6 @@ function fn6(): number {
|
|||
((): { a: true } => ({}) satisfies unknown)();
|
||||
((): { a: true } => ({ a: 1 }) satisfies unknown)();
|
||||
((): { a: true } => obj1 satisfies unknown)();
|
||||
|
||||
((): { a: true } => (({}) satisfies unknown) satisfies unknown)();
|
||||
((): { a: true } => ((({}) satisfies unknown)) satisfies unknown)();
|
||||
|
|
Загрузка…
Ссылка в новой задаче