mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
fix(isolated-declarations): inferring of UnrayExpression incorrectly (#3920)
close: #3914
This commit is contained in:
parent
3db2553dc2
commit
59ce38bb85
5 changed files with 75 additions and 6 deletions
|
|
@ -104,6 +104,10 @@ impl<'a> Expression<'a> {
|
|||
matches!(self, Self::StringLiteral(_) | Self::TemplateLiteral(_))
|
||||
}
|
||||
|
||||
pub fn is_number_literal(&self) -> bool {
|
||||
matches!(self, Self::NumericLiteral(_) | Self::BigIntLiteral(_))
|
||||
}
|
||||
|
||||
pub fn is_specific_string_literal(&self, string: &str) -> bool {
|
||||
match self {
|
||||
Self::StringLiteral(s) => s.value == string,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use oxc_allocator::Box;
|
||||
use oxc_ast::ast::{
|
||||
ArrowFunctionExpression, BindingPatternKind, Expression, FormalParameter, Function, Statement,
|
||||
TSType, TSTypeAnnotation,
|
||||
TSType, TSTypeAnnotation, UnaryExpression,
|
||||
};
|
||||
use oxc_span::{GetSpan, SPAN};
|
||||
|
||||
|
|
@ -14,6 +14,10 @@ use crate::{
|
|||
};
|
||||
|
||||
impl<'a> IsolatedDeclarations<'a> {
|
||||
pub fn can_infer_unary_expression(expr: &UnaryExpression<'a>) -> bool {
|
||||
expr.operator.is_arithmetic() && expr.argument.is_number_literal()
|
||||
}
|
||||
|
||||
pub fn infer_type_from_expression(&self, expr: &Expression<'a>) -> Option<TSType<'a>> {
|
||||
match expr {
|
||||
Expression::BooleanLiteral(_) => Some(self.ast.ts_boolean_keyword(SPAN)),
|
||||
|
|
@ -66,6 +70,13 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
self.infer_type_from_expression(&expr.expression)
|
||||
}
|
||||
Expression::TSTypeAssertion(expr) => Some(self.ast.copy(&expr.type_annotation)),
|
||||
Expression::UnaryExpression(expr) => {
|
||||
if Self::can_infer_unary_expression(expr) {
|
||||
self.infer_type_from_expression(&expr.argument)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -136,12 +147,13 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
.map(|type_annotation| self.ast.ts_type_annotation(SPAN, type_annotation))
|
||||
}
|
||||
|
||||
pub fn is_need_to_infer_type_from_expression(expr: &Expression) -> bool {
|
||||
pub fn is_need_to_infer_type_from_expression(expr: &Expression<'a>) -> bool {
|
||||
match expr {
|
||||
Expression::NumericLiteral(_)
|
||||
| Expression::BigIntLiteral(_)
|
||||
| Expression::StringLiteral(_) => false,
|
||||
Expression::TemplateLiteral(lit) => !lit.expressions.is_empty(),
|
||||
Expression::UnaryExpression(expr) => !Self::can_infer_unary_expression(expr),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,9 +192,16 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
Expression::TemplateLiteral(lit) => self
|
||||
.transform_template_to_string(lit)
|
||||
.map(|string| self.ast.ts_literal_type(lit.span, TSLiteral::StringLiteral(string))),
|
||||
Expression::UnaryExpression(expr) => Some(
|
||||
self.ast.ts_literal_type(SPAN, TSLiteral::UnaryExpression(self.ast.copy(expr))),
|
||||
),
|
||||
Expression::UnaryExpression(expr) => {
|
||||
if Self::can_infer_unary_expression(expr) {
|
||||
Some(
|
||||
self.ast
|
||||
.ts_literal_type(SPAN, TSLiteral::UnaryExpression(self.ast.copy(expr))),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Expression::ArrayExpression(expr) => {
|
||||
Some(self.transform_array_expression_to_ts_type(expr, true))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
// Correct
|
||||
|
||||
// ParenthesizedExpression
|
||||
const n = (0);
|
||||
const s = ("");
|
||||
const t = (``);
|
||||
const b = (true);
|
||||
const b = (true);
|
||||
|
||||
// UnaryExpression
|
||||
let unaryA = +12;
|
||||
const unaryB = -1_2n;
|
||||
|
||||
// Incorrect
|
||||
|
||||
// UnaryExpression
|
||||
const unaryC = +"str"
|
||||
const unaryD = typeof "str"
|
||||
const unaryE = {E: -"str"} as const
|
||||
|
|
@ -8,3 +8,36 @@ declare const n: number;
|
|||
declare const s: string;
|
||||
declare const t: string;
|
||||
declare const b: boolean;
|
||||
declare let unaryA: number;
|
||||
declare const unaryB = -1_2n;
|
||||
declare const unaryC: unknown;
|
||||
declare const unaryD: unknown;
|
||||
declare const unaryE: {};
|
||||
|
||||
|
||||
==================== Errors ====================
|
||||
|
||||
x TS9010: Variable must have an explicit type annotation with
|
||||
| --isolatedDeclarations.
|
||||
,-[16:7]
|
||||
15 | // UnaryExpression
|
||||
16 | const unaryC = +"str"
|
||||
: ^^^^^^
|
||||
17 | const unaryD = typeof "str"
|
||||
`----
|
||||
|
||||
x TS9010: Variable must have an explicit type annotation with
|
||||
| --isolatedDeclarations.
|
||||
,-[17:7]
|
||||
16 | const unaryC = +"str"
|
||||
17 | const unaryD = typeof "str"
|
||||
: ^^^^^^
|
||||
18 | const unaryE = {E: -"str"} as const
|
||||
`----
|
||||
|
||||
x TS9013: Expression type can't be inferred with --isolatedDeclarations.
|
||||
,-[18:20]
|
||||
17 | const unaryD = typeof "str"
|
||||
18 | const unaryE = {E: -"str"} as const
|
||||
: ^^^^^^
|
||||
`----
|
||||
|
|
|
|||
Loading…
Reference in a new issue