From 1f557ae524c23bc1f1e698cfa512fd00904d7cc5 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 17 Dec 2023 22:14:45 -0500 Subject: [PATCH 1/3] fix(eslint-plugin): [no-unnecesary-type-assertion] treat unknown/any as nullable --- .../src/rules/no-unnecessary-condition.ts | 11 +++----- .../src/rules/prefer-nullish-coalescing.ts | 3 +-- .../no-unnecessary-type-assertion.test.ts | 5 ++++ packages/type-utils/src/predicates.ts | 25 +++++++------------ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts index a55fd0d3956a..0309eae196ae 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-condition.ts @@ -530,7 +530,7 @@ export default createRule({ propertyType.value.toString(), ); if (propType) { - return isNullableType(propType, { allowUndefined: true }); + return isNullableType(propType); } } const typeName = getTypeName(checker, propertyType); @@ -568,14 +568,12 @@ export default createRule({ ); if (propType) { - return isNullableType(propType, { allowUndefined: true }); + return isNullableType(propType); } return !!checker.getIndexInfoOfType(type, ts.IndexKind.String); }); - return ( - !isOwnNullable && isNullableType(prevType, { allowUndefined: true }) - ); + return !isOwnNullable && isNullableType(prevType); } return false; } @@ -589,8 +587,7 @@ export default createRule({ const possiblyVoid = isTypeFlagSet(type, ts.TypeFlags.Void); return ( isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.Unknown) || - (isOwnNullable && - (isNullableType(type, { allowUndefined: true }) || possiblyVoid)) + (isOwnNullable && (isNullableType(type) || possiblyVoid)) ); } diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts index be498cb94ad0..c688d75d2771 100644 --- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts @@ -309,8 +309,7 @@ export default createRule({ ): void { const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node); const type = checker.getTypeAtLocation(tsNode.left); - const isNullish = isNullableType(type, { allowUndefined: true }); - if (!isNullish) { + if (!isNullableType(type)) { return; } diff --git a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts index 8cf362938bab..d4d2e11b7b7d 100644 --- a/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts @@ -48,6 +48,11 @@ const foo = { 0: 'hello', 5: 'hello' } as PossibleTuple; ` let bar: number | undefined = x; let foo: number = bar!; + `, + ` +declare const a: { data?: unknown }; + +const x = a.data!; `, { code: ` diff --git a/packages/type-utils/src/predicates.ts b/packages/type-utils/src/predicates.ts index fdc79dc45ac0..1910d8d8d918 100644 --- a/packages/type-utils/src/predicates.ts +++ b/packages/type-utils/src/predicates.ts @@ -8,25 +8,18 @@ const log = debug('typescript-eslint:eslint-plugin:utils:types'); /** * Checks if the given type is (or accepts) nullable - * @param isReceiver true if the type is a receiving type (i.e. the type of a called function's parameter) */ -export function isNullableType( - type: ts.Type, - { - isReceiver = false, - allowUndefined = true, - }: { isReceiver?: boolean; allowUndefined?: boolean } = {}, -): boolean { +export function isNullableType(type: ts.Type): boolean { const flags = getTypeFlags(type); - if (isReceiver && flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) { - return true; - } - - if (allowUndefined) { - return (flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) !== 0; - } - return (flags & ts.TypeFlags.Null) !== 0; + return ( + (flags & + (ts.TypeFlags.Any | + ts.TypeFlags.Unknown | + ts.TypeFlags.Null | + ts.TypeFlags.Undefined)) !== + 0 + ); } /** From 83a7b44c29cf9b41d2711d646087e2367dba0031 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Mon, 18 Dec 2023 15:08:18 -0500 Subject: [PATCH 2/3] Use isTypeFlagSet --- packages/type-utils/src/predicates.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/type-utils/src/predicates.ts b/packages/type-utils/src/predicates.ts index 1910d8d8d918..f5b01022237e 100644 --- a/packages/type-utils/src/predicates.ts +++ b/packages/type-utils/src/predicates.ts @@ -2,7 +2,7 @@ import debug from 'debug'; import * as tsutils from 'ts-api-utils'; import * as ts from 'typescript'; -import { getTypeFlags, isTypeFlagSet } from './typeFlagUtils'; +import { isTypeFlagSet } from './typeFlagUtils'; const log = debug('typescript-eslint:eslint-plugin:utils:types'); @@ -10,15 +10,12 @@ const log = debug('typescript-eslint:eslint-plugin:utils:types'); * Checks if the given type is (or accepts) nullable */ export function isNullableType(type: ts.Type): boolean { - const flags = getTypeFlags(type); - - return ( - (flags & - (ts.TypeFlags.Any | - ts.TypeFlags.Unknown | - ts.TypeFlags.Null | - ts.TypeFlags.Undefined)) !== - 0 + return isTypeFlagSet( + type, + ts.TypeFlags.Any | + ts.TypeFlags.Unknown | + ts.TypeFlags.Null | + ts.TypeFlags.Undefined, ); } From 948262fda69f1c39f51d7e35cd29f964827a7f41 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 11 Jan 2024 13:21:58 -0800 Subject: [PATCH 3/3] Update predicates.ts --- packages/type-utils/src/predicates.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/type-utils/src/predicates.ts b/packages/type-utils/src/predicates.ts index f5b01022237e..2fd45ac14598 100644 --- a/packages/type-utils/src/predicates.ts +++ b/packages/type-utils/src/predicates.ts @@ -9,7 +9,22 @@ const log = debug('typescript-eslint:eslint-plugin:utils:types'); /** * Checks if the given type is (or accepts) nullable */ -export function isNullableType(type: ts.Type): boolean { +export function isNullableType( + type: ts.Type, + { + isReceiver, + allowUndefined, + }?: { + /** + * @deprecated - this flag no longer does anything and will be removed in the next major + */ + isReceiver?: boolean; + /** + * @deprecated - this flag no longer does anything and will be removed in the next major + */ + allowUndefined?: boolean; + }, +): boolean { return isTypeFlagSet( type, ts.TypeFlags.Any | pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy