diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 6e01ef983ea4e..e06d43eb38e4a 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -1249,6 +1249,14 @@ pub enum VariableDeclarationKind { AwaitUsing = 4, } +/// A single variable declaration in a list of [variable declarations](VariableDeclaration). +/// +/// ## Examples +/// ```ts +/// // declarators may or may not have initializers +/// let foo, b = 1; +/// // ^^^ id ^ init +/// ``` #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 2a76e3ab6c7a6..44ea9e67815ba 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -1247,6 +1247,26 @@ pub struct TSInterfaceHeritage<'a> { pub type_parameters: Option>>, } +/// TypeScript Type Predicate +/// +/// ## Examples +/// ```ts +/// function isString(x: unknown): x is string { +/// // parameter_name ^ ^^^^^^ type_annotation +/// return typeof x === 'string'; +/// } +/// ``` +/// +/// ```ts +/// function assertString(x: unknown): asserts x is string { +/// // ^^^^^^^ asserts: true +/// if (typeof x !== 'string') throw new TypeError('x is not a string'); +/// } +/// ``` +/// +/// ## References +/// * [TypeScript Handbook - Type Predicates](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates) +/// * [TypeScript Handbook - Assertion Functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions) #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] @@ -1255,7 +1275,14 @@ pub struct TSInterfaceHeritage<'a> { pub struct TSTypePredicate<'a> { #[serde(flatten)] pub span: Span, + /// The identifier the predicate operates on pub parameter_name: TSTypePredicateName<'a>, + /// Does this predicate include an `asserts` modifier? + /// + /// ## Example + /// ```ts + /// declare function isString(x: any): asserts x is string; // true + /// ``` pub asserts: bool, pub type_annotation: Option>>, } @@ -1270,6 +1297,32 @@ pub enum TSTypePredicateName<'a> { This(TSThisType) = 1, } +/// TypeScript Module and Namespace Declarations +/// +/// ## Examples +/// ```ts +/// declare module 'foo' { +/// // kind ^^^^^^ ^^^^^ id +/// } +/// ``` +/// +/// ```ts +/// namespace Foo { } +/// declare namespace Bar { } +/// ``` +/// +/// ```ts +/// declare global { +/// interface Window { +/// customProp: string; +/// } +/// } +/// ``` +/// +/// ## References +/// * [TypeScript Handbook - Namespaces](https://www.typescriptlang.org/docs/handbook/2/modules.html#namespaces) +/// * [TypeScript Handbook - Module Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) +/// * [TypeScript Handbook - Global Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation) #[ast(visit)] #[scope( flags(ScopeFlags::TsModuleBlock), @@ -1285,8 +1338,12 @@ pub struct TSModuleDeclaration<'a> { pub id: TSModuleDeclarationName<'a>, #[scope(enter_before)] pub body: Option>, - /// The keyword used to define this module declaration - /// ```text + /// The keyword used to define this module declaration. + /// + /// Helps discriminate between global overrides vs module declarations vs namespace + /// declarations. + /// + /// ```ts /// namespace Foo {} /// ^^^^^^^^^ /// module 'foo' {} @@ -1307,8 +1364,11 @@ pub struct TSModuleDeclaration<'a> { #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSModuleDeclarationKind { + /// `declare global {}` Global = 0, + /// `declare module 'foo' {}` Module = 1, + /// `namespace Foo {}` Namespace = 2, } @@ -1326,6 +1386,26 @@ impl TSModuleDeclarationKind { } } +/// The name of a TypeScript [namespace or module declaration](TSModuleDeclaration). +/// +/// Note that it is a syntax error for namespace declarations to have a string literal name. +/// Modules may have either kind. +/// +/// ## Examples +/// ```ts +/// // TSModuleDeclarationName::StringLiteral +/// declare module "*.css" { +/// const styles: { [key: string]: string }; +/// export default styles; +/// } +/// ``` +/// +/// ```ts +/// // TSModuleDeclarationName::Identifier +/// namespace Foo { +/// export const bar = 42; +/// } +/// ``` #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] @@ -1461,7 +1541,8 @@ pub enum TSTypeQueryExprName<'a> { pub struct TSImportType<'a> { #[serde(flatten)] pub span: Span, - pub is_type_of: bool, // `typeof import("foo")` + /// `true` for `typeof import("foo")` + pub is_type_of: bool, pub parameter: TSType<'a>, pub qualifier: Option>, pub attributes: Option>>, @@ -1556,6 +1637,27 @@ pub struct TSConstructorType<'a> { pub type_parameters: Option>>, } +/// TypeScript Mapped Type +/// +/// ## Examples +/// ```ts +/// type Maybe = { +/// // _____ constraint +/// [P in keyof T]?: T[P] +/// // ^ type_parameter +/// } +/// ``` +/// +/// ```ts +/// type ReadonlyDefinite = { +/// // _ type parameter +/// readonly [P in keyof T]-?: T[P] +/// // ^^ `optional` modifier +/// }; +/// ``` +/// +/// ## References +/// * [TypeScript Handbook - Mapped Types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html) #[ast(visit)] #[scope] #[derive(Debug)] @@ -1565,10 +1667,33 @@ pub struct TSConstructorType<'a> { pub struct TSMappedType<'a> { #[serde(flatten)] pub span: Span, + /// Key type parameter, e.g. `P` in `[P in keyof T]`. pub type_parameter: Box<'a, TSTypeParameter<'a>>, pub name_type: Option>, pub type_annotation: Option>, + /// Optional modifier on type annotation + /// + /// ## Examples + /// ```ts + /// type Foo = { [P in keyof T]?: T[P] } + /// // ^^ True + /// type Bar = { [P in keyof T]+?: T[P] } + /// // ^^ Plus + /// type Baz = { [P in keyof T]-?: T[P] } + /// // ^^ Minus + /// type Qux = { [P in keyof T]: T[P] } + /// // ^ None + /// ``` pub optional: TSMappedTypeModifierOperator, + /// Readonly modifier before keyed index signature + /// + /// ## Examples + /// ```ts + /// type Foo = { readonly [P in keyof T]: T[P] } // True + /// type Bar = { +readonly [P in keyof T]: T[P] } // Plus + /// type Baz = { -readonly [P in keyof T]: T[P] } // Minus + /// type Qux = { [P in keyof T]: T[P] } // None + /// ``` pub readonly: TSMappedTypeModifierOperator, #[serde(skip)] #[clone_in(default)] @@ -1581,14 +1706,29 @@ pub struct TSMappedType<'a> { #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[serde(rename_all = "camelCase")] pub enum TSMappedTypeModifierOperator { + /// e.g. `?` in `{ [P in K]?: T }` True = 0, + /// e.g. `+?` in `{ [P in K]+?: T }` #[serde(rename = "+")] Plus = 1, + /// e.g. `-?` in `{ [P in K]-?: T }` #[serde(rename = "-")] Minus = 2, + /// No modifier present None = 3, } +/// TypeScript Template Literal Type +/// +/// ## Example +/// ```ts +/// // Each string part is an element in `quasis`, including empty strings at the beginning/end. +/// // In this example, `quasis` has 3 elements: ["", ".", ""] +/// type Dot = `${T}.${U}`; +/// ``` +/// +/// ## Reference +/// * [TypeScript Handbook - Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html#handbook-content) #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] @@ -1597,7 +1737,9 @@ pub enum TSMappedTypeModifierOperator { pub struct TSTemplateLiteralType<'a> { #[serde(flatten)] pub span: Span, + /// The string parts of the template literal. pub quasis: Vec<'a, TemplateElement<'a>>, + /// The interpolated expressions in the template literal. pub types: Vec<'a, TSType<'a>>, } @@ -1613,6 +1755,18 @@ pub struct TSAsExpression<'a> { pub type_annotation: TSType<'a>, } +/// TypeScript `satisfies` Expression +/// +/// ## Example +/// ```ts +/// const user = { +/// id: 0, +/// name: 'Alice', +/// } satisfies User; +/// ``` +/// +/// ## Reference +/// * [TypeScript Handbook - The `satisfies` Operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator) #[ast(visit)] #[derive(Debug)] #[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)] @@ -1621,7 +1775,9 @@ pub struct TSAsExpression<'a> { pub struct TSSatisfiesExpression<'a> { #[serde(flatten)] pub span: Span, + /// The value expression being constrained. pub expression: Expression<'a>, + /// The type `expression` must satisfy. pub type_annotation: TSType<'a>, } diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index a372c5cecd536..f89659aab6582 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -1347,8 +1347,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - expression - /// - type_annotation + /// - expression: The value expression being constrained. + /// - type_annotation: The type `expression` must satisfy. #[inline] pub fn expression_ts_satisfies( self, @@ -2853,8 +2853,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - expression - /// - type_annotation + /// - expression: The value expression being constrained. + /// - type_annotation: The type `expression` must satisfy. #[inline] pub fn simple_assignment_target_ts_satisfies_expression( self, @@ -4419,7 +4419,7 @@ impl<'a> AstBuilder<'a> { /// - span: The [`Span`] covering this node /// - id /// - body - /// - kind: The keyword used to define this module declaration + /// - kind: The keyword used to define this module declaration. /// - declare #[inline] pub fn declaration_ts_module( @@ -8839,7 +8839,7 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - is_type_of + /// - is_type_of: `true` for `typeof import("foo")` /// - parameter /// - qualifier /// - attributes @@ -8980,11 +8980,11 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - type_parameter + /// - type_parameter: Key type parameter, e.g. `P` in `[P in keyof T]`. /// - name_type /// - type_annotation - /// - optional - /// - readonly + /// - optional: Optional modifier on type annotation + /// - readonly: Readonly modifier before keyed index signature #[inline] pub fn ts_type_mapped_type( self, @@ -9084,8 +9084,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - quasis - /// - types + /// - quasis: The string parts of the template literal. + /// - types: The interpolated expressions in the template literal. #[inline] pub fn ts_type_template_literal_type( self, @@ -9210,8 +9210,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - parameter_name - /// - asserts + /// - parameter_name: The identifier the predicate operates on + /// - asserts: Does this predicate include an `asserts` modifier? /// - type_annotation #[inline] pub fn ts_type_type_predicate( @@ -11281,8 +11281,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - parameter_name - /// - asserts + /// - parameter_name: The identifier the predicate operates on + /// - asserts: Does this predicate include an `asserts` modifier? /// - type_annotation #[inline] pub fn ts_type_predicate( @@ -11309,8 +11309,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - parameter_name - /// - asserts + /// - parameter_name: The identifier the predicate operates on + /// - asserts: Does this predicate include an `asserts` modifier? /// - type_annotation #[inline] pub fn alloc_ts_type_predicate( @@ -11383,7 +11383,7 @@ impl<'a> AstBuilder<'a> { /// - span: The [`Span`] covering this node /// - id /// - body - /// - kind: The keyword used to define this module declaration + /// - kind: The keyword used to define this module declaration. /// - declare #[inline] pub fn ts_module_declaration( @@ -11405,7 +11405,7 @@ impl<'a> AstBuilder<'a> { /// - span: The [`Span`] covering this node /// - id /// - body - /// - kind: The keyword used to define this module declaration + /// - kind: The keyword used to define this module declaration. /// - declare #[inline] pub fn alloc_ts_module_declaration( @@ -11485,7 +11485,7 @@ impl<'a> AstBuilder<'a> { /// - span: The [`Span`] covering this node /// - id /// - body - /// - kind: The keyword used to define this module declaration + /// - kind: The keyword used to define this module declaration. /// - declare #[inline] pub fn ts_module_declaration_body_module_declaration( @@ -11691,7 +11691,7 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - is_type_of + /// - is_type_of: `true` for `typeof import("foo")` /// - parameter /// - qualifier /// - attributes @@ -11743,7 +11743,7 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - is_type_of + /// - is_type_of: `true` for `typeof import("foo")` /// - parameter /// - qualifier /// - attributes @@ -11778,7 +11778,7 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - is_type_of + /// - is_type_of: `true` for `typeof import("foo")` /// - parameter /// - qualifier /// - attributes @@ -12074,11 +12074,11 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - type_parameter + /// - type_parameter: Key type parameter, e.g. `P` in `[P in keyof T]`. /// - name_type /// - type_annotation - /// - optional - /// - readonly + /// - optional: Optional modifier on type annotation + /// - readonly: Readonly modifier before keyed index signature #[inline] pub fn ts_mapped_type( self, @@ -12109,11 +12109,11 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - type_parameter + /// - type_parameter: Key type parameter, e.g. `P` in `[P in keyof T]`. /// - name_type /// - type_annotation - /// - optional - /// - readonly + /// - optional: Optional modifier on type annotation + /// - readonly: Readonly modifier before keyed index signature #[inline] pub fn alloc_ts_mapped_type( self, @@ -12146,8 +12146,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - quasis - /// - types + /// - quasis: The string parts of the template literal. + /// - types: The interpolated expressions in the template literal. #[inline] pub fn ts_template_literal_type( self, @@ -12164,8 +12164,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - quasis - /// - types + /// - quasis: The string parts of the template literal. + /// - types: The interpolated expressions in the template literal. #[inline] pub fn alloc_ts_template_literal_type( self, @@ -12218,8 +12218,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - expression - /// - type_annotation + /// - expression: The value expression being constrained. + /// - type_annotation: The type `expression` must satisfy. #[inline] pub fn ts_satisfies_expression( self, @@ -12236,8 +12236,8 @@ impl<'a> AstBuilder<'a> { /// /// ## Parameters /// - span: The [`Span`] covering this node - /// - expression - /// - type_annotation + /// - expression: The value expression being constrained. + /// - type_annotation: The type `expression` must satisfy. #[inline] pub fn alloc_ts_satisfies_expression( self,