diff --git a/docs/reference/msbuild-props.md b/docs/reference/msbuild-props.md
index 4b82b350..7d737e2b 100644
--- a/docs/reference/msbuild-props.md
+++ b/docs/reference/msbuild-props.md
@@ -7,6 +7,7 @@ The following properties can be used to customize the build processes for genera
| `GenerateNodeApiTypeDefinitions` | Set to `true` to generate TypeScript type definitions for .NET APIs in the current project. (This is enabled by default when referencing the `Microsoft.JavaScript.NodeApi.Generator` package.) See [Develop a Node.js addon module](../scenarios/js-dotnet-module). |
| `GenerateNodeApiTypeDefinitionsForReferences` | Set to `true` to generate TypeScript type definitions for .NET APIs in assemblies referenced by the current project. (This is enabled by default when **_an empty project_** references the `Microsoft.JavaScript.NodeApi.Generator` package.) See [Dynamically invoke .NET APIs from JavaScript](../scenarios/js-dotnet-dynamic). |
| `NodeApiTypeDefinitionsFileName` | Name of the type-definitions file generated for a project. Defaults to `$(TargetName).d.ts`. |
+| `NodeApiTypeDefinitionsEnableWarnings` | Set to `true` to enable warnings when [generating type definitions](../features/type-definitions). The warnings are suppressed by default because they can be verbose when referencing system or external assemblies.
| `NodeApiJSModuleType` | Set to either `commonjs` or `esm` to specify the module system used by the generated type definitions. If unspecified, the module type is detected automatically from `package.json`, which is usually correct. |
| `NodeApiSystemReferenceAssembly` | Item-list of assembly names (not file paths) to be included in typedefs generator. The `System`, `System.Runtime`, and `System.Console` assemblies are included by default. Add system assembly names to the item-list to generate type definitions for them. System assemblies are provided by the installed .NET SDK. |
| `PublishNodeModule` | Set to `true` to produce a Native AOT `.node` binary and `.js` module-loader script when building the `Publish` target. The files will be placed in the directory indicated by the `PublishDir` variable. See [Develop a Node.js addon module with .NET Native AOT](../scenarios/js-aot-module). |
diff --git a/src/NodeApi.Generator/NodeApi.Generator.targets b/src/NodeApi.Generator/NodeApi.Generator.targets
index 0282de65..f72220c4 100644
--- a/src/NodeApi.Generator/NodeApi.Generator.targets
+++ b/src/NodeApi.Generator/NodeApi.Generator.targets
@@ -139,10 +139,6 @@
Outputs="@(NodeApiReferenceAssemblies->'$(TargetDir)%(Filename).d.ts')"
Condition=" '$(GenerateNodeApiTypeDefinitions)' == 'true' AND '$(Compile)' == '' "
>
-
- <_SuppressTSGenerationWarnings>--nowarn
-
-
@@ -172,6 +168,7 @@
+
diff --git a/src/NodeApi.Generator/TypeDefinitionsGenerator.cs b/src/NodeApi.Generator/TypeDefinitionsGenerator.cs
index 4f3eca63..a16fd6d3 100644
--- a/src/NodeApi.Generator/TypeDefinitionsGenerator.cs
+++ b/src/NodeApi.Generator/TypeDefinitionsGenerator.cs
@@ -2332,12 +2332,66 @@ private static string FormatDocMemberParameterType(
private static string TSIdentifier(string? identifier)
{
- return identifier switch
- {
- // A method parameter named "function" is valid in C# but invalid in TS.
- "function" => "_" + identifier,
- null => "_",
- _ => identifier,
- };
+ return string.IsNullOrEmpty(identifier) ? "_" :
+ s_tsReservedWords.Contains(identifier) ? "_" + identifier : identifier;
}
+
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words
+ private static readonly HashSet s_tsReservedWords = new()
+ {
+ "arguments",
+ "as",
+ "async",
+ "await",
+ "break",
+ "case",
+ "catch",
+ "class",
+ "const",
+ "continue",
+ "debugger",
+ "default",
+ "delete",
+ "do",
+ "else",
+ "enum",
+ "eval",
+ "export",
+ "extends",
+ "false",
+ "finally",
+ "for",
+ "from",
+ "function",
+ "get",
+ "if",
+ "implements",
+ "import",
+ "in",
+ "instanceof",
+ "interface",
+ "let",
+ "new",
+ "null",
+ "of",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "return",
+ "set",
+ "static",
+ "super",
+ "switch",
+ "this",
+ "throw",
+ "true",
+ "try",
+ "typeof",
+ "var",
+ "void",
+ "while",
+ "with",
+ "yield",
+ };
}
diff --git a/test/TypeDefsGeneratorTests.cs b/test/TypeDefsGeneratorTests.cs
index 992876dc..14d57633 100644
--- a/test/TypeDefsGeneratorTests.cs
+++ b/test/TypeDefsGeneratorTests.cs
@@ -71,14 +71,14 @@ export interface SimpleInterface {
TestProperty: string;
/** method */
- TestMethod(): string;
+ TestMethod(_default: string | undefined): string;
}
""".ReplaceLineEndings(),
GenerateTypeDefinition(typeof(SimpleInterface), new Dictionary
{
["T:SimpleInterface"] = "interface",
["P:SimpleInterface.TestProperty"] = "property",
- ["M:SimpleInterface.TestMethod"] = "method",
+ ["M:SimpleInterface.TestMethod(System.String)"] = "method",
}));
}
@@ -96,7 +96,7 @@ export class SimpleClass implements SimpleInterface {
TestProperty: string;
/** method */
- TestMethod(): string;
+ TestMethod(_default: string | undefined): string;
}
""".ReplaceLineEndings(),
GenerateTypeDefinition(typeof(SimpleClass), new Dictionary
@@ -104,7 +104,7 @@ export class SimpleClass implements SimpleInterface {
["T:SimpleClass"] = "class",
["M:SimpleClass.#ctor"] = "constructor",
["P:SimpleClass.TestProperty"] = "property",
- ["M:SimpleClass.TestMethod"] = "method",
+ ["M:SimpleClass.TestMethod(System.String)"] = "method",
}));
}
@@ -120,7 +120,7 @@ public void GenerateSimpleProperty()
[Fact]
public void GenerateSimpleMethod()
{
- Assert.Equal(@"TestMethod(): string;",
+ Assert.Equal(@"TestMethod(_default: string | undefined): string;",
GenerateMemberDefinition(
typeof(SimpleClass).GetMethod(nameof(SimpleClass.TestMethod))!,
new Dictionary()));
@@ -250,7 +250,7 @@ public void GenerateJSDocLink()
export interface SimpleInterface {
TestProperty: string;
- TestMethod(): string;
+ TestMethod(_default: string | undefined): string;
}
""".ReplaceLineEndings(),
GenerateTypeDefinition(typeof(SimpleInterface), new Dictionary
@@ -296,13 +296,13 @@ export interface SimpleClass {
public interface SimpleInterface
{
string TestProperty { get; set; }
- string TestMethod();
+ string TestMethod(string? @default); // 'default' is a reserved word in JS
}
public class SimpleClass : SimpleInterface
{
public string TestProperty { get; set; } = null!;
- public string TestMethod() { return string.Empty; }
+ public string TestMethod(string? @default) { return @default ?? string.Empty; }
}
public delegate void SimpleDelegate(string arg);
@@ -334,9 +334,9 @@ public class GenericClass : GenericInterface
public static class SimpleClassExtensions
{
public static void TestExtensionA(this SimpleClass value)
- => value.TestMethod();
+ => value.TestMethod(null);
public static void TestExtensionB(this SimpleClass value)
- => value.TestMethod();
+ => value.TestMethod(null);
}
#endif