diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 259e0032e0c495742122f420e60cccde06df7411..3ed10f6daa0e06b99d331a8c189cb036b546d1fa 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -1812,13 +1812,14 @@ void ETSChecker::BindingsModuleObjectAddProperty(checker::ETSObjectType *moduleO for (auto [_, var] : bindings) { (void)_; auto [found, aliasedName] = FindSpecifierForModuleObject(importDecl, var->AsLocalVariable()->Name()); - if (!var->AsLocalVariable()->Declaration()->Node()->IsValidInCurrentPhase()) { + auto node = var->AsLocalVariable()->Declaration()->Node(); + if (!node->IsValidInCurrentPhase()) { continue; } - if ((var->AsLocalVariable()->Declaration()->Node()->IsExported() || - var->AsLocalVariable()->Declaration()->Node()->HasExportAlias()) && - found) { - if (var->AsLocalVariable()->Declaration()->Node()->IsMethodDefinition()) { + auto isFromDynamicDefaultImport = + (node->IsDefaultExported() && var->HasFlag(varbinder::VariableFlags::DYNAMIC)); + if ((node->IsExported() || isFromDynamicDefaultImport || node->HasExportAlias()) && found) { + if (node->IsMethodDefinition()) { BuildExportedFunctionSignature(this, var); } @@ -2858,7 +2859,7 @@ void ETSChecker::GenerateGetterSetterBody(ArenaVector &stmts, A memberExpression->SetPropVar(field->Key()->Variable()->AsLocalVariable()); memberExpression->SetRange(classDef->Range()); if (memberExpression->ObjType() == nullptr && classDef->TsType() != nullptr) { - memberExpression->SetObjectType(classDef->TsType()->AsETSObjectType()); + memberExpression->SetObjectType(classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType()); } if (!isSetter) { diff --git a/ets2panda/compiler/base/lexenv.cpp b/ets2panda/compiler/base/lexenv.cpp index e9abb4a6152a300234fe51089b57a95bd622677b..6c2906d857e13bc7bf46f1fe39dc1f00c081bf95 100644 --- a/ets2panda/compiler/base/lexenv.cpp +++ b/ets2panda/compiler/base/lexenv.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -80,7 +80,7 @@ static void StoreLocalExport(PandaGen *pg, const ir::AstNode *node, varbinder::V auto range = pg->Scope()->AsModuleScope()->LocalExports().equal_range(variable); for (auto it = range.first; it != range.second; ++it) { - if (it->second != "default") { + if (it->second != compiler::Signatures::DEFAULT) { pg->StoreModuleVar(node, it->second); } } diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index fc921010efd67abd01808af32ff58f76ca59f6a1..437b408c96f317084d0b2b771fda1b083efa4baa 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -706,7 +706,9 @@ void ETSCompiler::CompileAny(const ir::CallExpression *expr, const ir::Expressio etsg->StoreAccumulator(expr, objReg); auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); if (expr->Signature()->Function() != nullptr && expr->Signature()->Function()->IsStatic()) { - etsg->LoadPropertyByNameAny(memberExpr, objReg, memberExpr->Property()->AsIdentifier()->Name()); + auto name = expr->Signature()->Function()->IsDefaultExported() ? compiler::Signatures::DEFAULT + : memberExpr->Property()->AsIdentifier()->Name(); + etsg->LoadPropertyByNameAny(memberExpr, objReg, name); etsg->StoreAccumulator(expr, calleeReg); etsg->CallAny(callee->AsMemberExpression()->Object(), Span(expr->Arguments()), calleeReg); @@ -909,7 +911,12 @@ bool ETSCompiler::CompileAny(compiler::ETSGen *etsg, const ir::MemberExpression etsg->StoreAccumulator(expr, objReg); auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); - etsg->LoadPropertyByNameAny(expr, objReg, expr->Property()->AsIdentifier()->Name()); + if (expr->Property()->Variable()->Declaration() != nullptr && + expr->Property()->Variable()->Declaration()->Node()->IsDefaultExported()) { + etsg->LoadPropertyByNameAny(expr, objReg, compiler::Signatures::DEFAULT); + } else { + etsg->LoadPropertyByNameAny(expr, objReg, expr->Property()->AsIdentifier()->Name()); + } etsg->EmitAnyCheckCast(expr, expr->TsType()); return true; } diff --git a/ets2panda/compiler/lowering/ets/dynamicImport.cpp b/ets2panda/compiler/lowering/ets/dynamicImport.cpp index 5e848f6e1eefdc7a976e7820b1dd46a056b90a22..7d27f20b77c92701cf0412e84a5ef2419dec6516 100644 --- a/ets2panda/compiler/lowering/ets/dynamicImport.cpp +++ b/ets2panda/compiler/lowering/ets/dynamicImport.cpp @@ -192,15 +192,18 @@ static void FillVarMapForImportSpecifiers(const ArenaVector &spec ArenaUnorderedMap &varMap) { for (auto specifier : specifiers) { + varbinder::Variable *var = nullptr; if (specifier->IsImportSpecifier()) { - auto *var = specifier->AsImportSpecifier()->Imported()->Variable(); - var->AddFlag(varbinder::VariableFlags::DYNAMIC); - varMap.insert({var, classDef}); + var = specifier->AsImportSpecifier()->Imported()->Variable(); } else if (specifier->IsImportNamespaceSpecifier()) { - auto *var = specifier->AsImportNamespaceSpecifier()->Local()->Variable(); - var->AddFlag(varbinder::VariableFlags::DYNAMIC); - varMap.insert({var, classDef}); + var = specifier->AsImportNamespaceSpecifier()->Local()->Variable(); + } else if (specifier->IsImportDefaultSpecifier()) { + var = specifier->AsImportDefaultSpecifier()->Local()->Variable(); + } else { + ES2PANDA_UNREACHABLE(); } + var->AddFlag(varbinder::VariableFlags::DYNAMIC); + varMap.insert({var, classDef}); } } @@ -280,7 +283,8 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context auto varBinder = checker->VarBinder()->AsETSBinder(); auto allocator = checker->ProgramAllocator(); if (ident->Variable()->Declaration() != nullptr && ident->Variable()->Declaration()->Node() != nullptr && - ident->Variable()->Declaration()->Node()->IsImportNamespaceSpecifier()) { + (ident->Variable()->Declaration()->Node()->IsImportNamespaceSpecifier() || + ident->Variable()->Declaration()->Node()->IsImportDefaultSpecifier())) { return ident; } @@ -288,8 +292,8 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context auto isTransformedNode = (parent->IsMemberExpression() && parent->AsMemberExpression()->ObjType() != nullptr && parent->AsMemberExpression()->ObjType()->HasObjectFlag(checker::ETSObjectFlags::LAZY_IMPORT_OBJECT)); - if (parent->IsImportSpecifier() || parent->IsImportNamespaceSpecifier() || parent->IsScriptFunction() || - parent->IsMethodDefinition() || isTransformedNode) { + if (parent->IsImportSpecifier() || parent->IsImportNamespaceSpecifier() || parent->IsImportDefaultSpecifier() || + parent->IsScriptFunction() || parent->IsMethodDefinition() || isTransformedNode) { return ident; } diff --git a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp index a497f98264a7bcae6d5f76bc343b823ce2a0b958..a899908b80b42d70310d2c1488be2cbfbd1340e8 100644 --- a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp @@ -321,7 +321,7 @@ static ir::AstNode *HandleDynamicObjectLiteralLowering(public_lib::Context *ctx, }; const size_t genSymId = appendArgument(gensym->Clone(allocator, nullptr)); - const size_t valueId = appendArgument(property->AsProperty()->Value()->Clone(allocator, nullptr)); + const size_t valueId = appendArgument(property->AsProperty()->Value()); ss << "@@I" << genSymId << ".setProperty('" << property->AsProperty()->Key()->DumpEtsSrc() << "', ESValue.wrap(@@E" << valueId << "));"; diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 468a7154ae98ba613a45d75ab36dc174a86c48a4..2e06978b5f8f1d2babe90f3bf4eae22d46b57199 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -259,6 +259,8 @@ defines: ref: CONSTRUCTOR_NAME - name: 'delete' ref: DELETE + - name: 'default' + ref: DEFAULT packages: - name: 'std.core' diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_namespace.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_namespace.ets index 2ea885ad62afc35ddf3ff692e6cb51308a0efa6f..aacc4d6905b50b5389566abfd742984e5d805e6b 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_namespace.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_namespace.ets @@ -17,8 +17,8 @@ flags: [dynamic-ast] ---*/ -import { ns } from "dynamic_import_tests/modules/module" +import ns from "dynamic_import_tests/modules/module" -()=>{ +() => { let a = new ns.A() } diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt index f1cbb6855aa656dc354f86a783029da031f3a9dd..82fb53dad3e94d45fc1de928eb7c7204a55f5000 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt @@ -1163,12 +1163,12 @@ "loc": { "start": { "line": 30, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1176,12 +1176,12 @@ "loc": { "start": { "line": 30, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1189,12 +1189,12 @@ "loc": { "start": { "line": 30, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1207,7 +1207,7 @@ }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1220,7 +1220,7 @@ }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1288,12 +1288,12 @@ "loc": { "start": { "line": 30, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1301,12 +1301,12 @@ "loc": { "start": { "line": 30, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1314,12 +1314,12 @@ "loc": { "start": { "line": 30, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1359,7 +1359,7 @@ }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1372,7 +1372,7 @@ }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1386,7 +1386,7 @@ }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -1400,7 +1400,7 @@ }, "end": { "line": 30, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -2121,12 +2121,12 @@ "loc": { "start": { "line": 40, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 40, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -2134,12 +2134,12 @@ "loc": { "start": { "line": 40, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 40, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -2147,12 +2147,12 @@ "loc": { "start": { "line": 40, - "column": 7, + "column": 8, "program": "module.ets" }, "end": { "line": 40, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -2166,7 +2166,7 @@ }, "end": { "line": 40, - "column": 13, + "column": 14, "program": "module.ets" } } @@ -2470,12 +2470,12 @@ "loc": { "start": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" }, "end": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" } } @@ -2494,12 +2494,12 @@ "loc": { "start": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" }, "end": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" } } @@ -2514,12 +2514,12 @@ "loc": { "start": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" }, "end": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" } } @@ -2527,12 +2527,12 @@ "loc": { "start": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" }, "end": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" } } @@ -2540,12 +2540,12 @@ "loc": { "start": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" }, "end": { "line": 45, - "column": 25, + "column": 26, "program": "module.ets" } } @@ -2568,7 +2568,7 @@ "loc": { "start": { "line": 45, - "column": 24, + "column": 25, "program": "module.ets" }, "end": { @@ -2599,12 +2599,12 @@ "loc": { "start": { "line": 47, - "column": 28, + "column": 29, "program": "module.ets" }, "end": { "line": 47, - "column": 30, + "column": 32, "program": "module.ets" } } @@ -2634,7 +2634,7 @@ }, "end": { "line": 47, - "column": 30, + "column": 32, "program": "module.ets" } } @@ -2761,7 +2761,7 @@ }, "end": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" } } @@ -2776,12 +2776,12 @@ "loc": { "start": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" }, "end": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" } } @@ -2800,12 +2800,12 @@ "loc": { "start": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" }, "end": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" } } @@ -2820,12 +2820,12 @@ "loc": { "start": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" }, "end": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" } } @@ -2833,12 +2833,12 @@ "loc": { "start": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" }, "end": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" } } @@ -2846,12 +2846,12 @@ "loc": { "start": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" }, "end": { "line": 49, - "column": 50, + "column": 51, "program": "module.ets" } } @@ -2874,7 +2874,7 @@ "loc": { "start": { "line": 49, - "column": 49, + "column": 50, "program": "module.ets" }, "end": { @@ -2959,12 +2959,12 @@ "loc": { "start": { "line": 51, - "column": 10, + "column": 11, "program": "module.ets" }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -2972,12 +2972,12 @@ "loc": { "start": { "line": 51, - "column": 10, + "column": 11, "program": "module.ets" }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -2985,12 +2985,12 @@ "loc": { "start": { "line": 51, - "column": 10, + "column": 11, "program": "module.ets" }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3003,7 +3003,7 @@ }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3016,7 +3016,7 @@ }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3084,12 +3084,12 @@ "loc": { "start": { "line": 51, - "column": 10, + "column": 11, "program": "module.ets" }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3097,12 +3097,12 @@ "loc": { "start": { "line": 51, - "column": 10, + "column": 11, "program": "module.ets" }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3110,12 +3110,12 @@ "loc": { "start": { "line": 51, - "column": 10, + "column": 11, "program": "module.ets" }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3155,7 +3155,7 @@ }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3168,7 +3168,7 @@ }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3182,7 +3182,7 @@ }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3196,7 +3196,7 @@ }, "end": { "line": 51, - "column": 16, + "column": 17, "program": "module.ets" } } @@ -3258,12 +3258,12 @@ "loc": { "start": { "line": 52, - "column": 9, + "column": 10, "program": "module.ets" }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3271,12 +3271,12 @@ "loc": { "start": { "line": 52, - "column": 9, + "column": 10, "program": "module.ets" }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3284,12 +3284,12 @@ "loc": { "start": { "line": 52, - "column": 9, + "column": 10, "program": "module.ets" }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3302,7 +3302,7 @@ }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3315,7 +3315,7 @@ }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3383,12 +3383,12 @@ "loc": { "start": { "line": 52, - "column": 9, + "column": 10, "program": "module.ets" }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3396,12 +3396,12 @@ "loc": { "start": { "line": 52, - "column": 9, + "column": 10, "program": "module.ets" }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3409,12 +3409,12 @@ "loc": { "start": { "line": 52, - "column": 9, + "column": 10, "program": "module.ets" }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3454,7 +3454,7 @@ }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3467,7 +3467,7 @@ }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3481,7 +3481,7 @@ }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -3495,7 +3495,7 @@ }, "end": { "line": 52, - "column": 15, + "column": 16, "program": "module.ets" } } @@ -4258,7 +4258,7 @@ "loc": { "start": { "line": 63, - "column": 43, + "column": 44, "program": "module.ets" }, "end": { @@ -4866,12 +4866,12 @@ "loc": { "start": { "line": 55, - "column": 26, + "column": 34, "program": "module.ets" }, "end": { "line": 55, - "column": 28, + "column": 36, "program": "module.ets" } } @@ -4909,12 +4909,12 @@ "loc": { "start": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" }, "end": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" } } @@ -4933,12 +4933,12 @@ "loc": { "start": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" }, "end": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" } } @@ -4953,12 +4953,12 @@ "loc": { "start": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" }, "end": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" } } @@ -4966,12 +4966,12 @@ "loc": { "start": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" }, "end": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" } } @@ -4979,12 +4979,12 @@ "loc": { "start": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" }, "end": { "line": 56, - "column": 20, + "column": 21, "program": "module.ets" } } @@ -5007,7 +5007,7 @@ "loc": { "start": { "line": 56, - "column": 19, + "column": 20, "program": "module.ets" }, "end": { @@ -5034,7 +5034,7 @@ "loc": { "start": { "line": 55, - "column": 16, + "column": 24, "program": "module.ets" }, "end": { @@ -5047,7 +5047,7 @@ "loc": { "start": { "line": 55, - "column": 16, + "column": 24, "program": "module.ets" }, "end": { @@ -5065,8 +5065,8 @@ "program": "module.ets" }, "end": { - "line": 65, - "column": 2, + "line": 66, + "column": 1, "program": "module.ets" } } diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets index e36d742f6a5d09805167479813912b7a94f377cf..9e3f67d756cced10733fa18c1c5e46dcf7a7c380 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets @@ -27,7 +27,7 @@ export declare class A { optional_foo(p?: double): string; } export declare interface I { - s:string + s: string f1(p: string): double; f2(p: double): string; } @@ -37,29 +37,29 @@ export declare abstract class Animal { } export declare class C { - s:string + s: string } export declare type requiredC = Required -export declare class C1{} +export declare class C1 { } -export declare interface I1{} +export declare interface I1 { } -export declare class C2 extends C1 implements I1{} +export declare class C2 extends C1 implements I1 { } export declare interface I2 extends I1 { - name:string; - age:number + name: string; + age: number } -export declare namespace ns { - export class A{} +export default declare namespace ns { + export class A { } } export declare class MyError extends Error { mycode: number } -export declare interface OptionalInterface{ +export declare interface OptionalInterface { s?: string -} \ No newline at end of file +}