{"id":11141,"date":"2024-12-22T11:03:03","date_gmt":"2024-12-22T11:03:03","guid":{"rendered":"https:\/\/putridparrot.com\/blog\/?p=11141"},"modified":"2024-12-22T11:04:15","modified_gmt":"2024-12-22T11:04:15","slug":"blazor-and-typescript","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/blazor-and-typescript\/","title":{"rendered":"Blazor and TypeScript"},"content":{"rendered":"<p>In the past I wrote a blog post on <a href=\"https:\/\/putridparrot.com\/blog\/blazor-and-the-javascript-interop\/\" target=\"_blank\">Blazor and the JavaScript interop.<\/a> but what about TypeScript, I mean it obviously transpiles to JavaScript, so we should be able to use it, right ?<\/p>\n<p>So yes, we can easily use TypeScript within a Blazor application, let&#8217;s do the following<\/p>\n<ul>\n<li>Create a Blazor WebAssembly Standalone App (you can use the server one&#8217;s if you prefer, but for this post that&#8217;s the template I&#8217;m starting with)<\/li>\n<li>Add the NuGet Package Microsoft.TypeScript.MSBuild, this will allow us to transpile our TypeSript code as part of the build process. This will add the following to the csproj (the version may differ ofcourse)\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&lt;PackageReference Include=&quot;Microsoft.TypeScript.MSBuild&quot; Version=&quot;5.7.1&quot;&gt;\r\n  &lt;PrivateAssets&gt;all&lt;\/PrivateAssets&gt;\r\n  &lt;IncludeAssets&gt;runtime; build; native; contentfiles; analyzers; buildtransitive&lt;\/IncludeAssets&gt;\r\n&lt;\/PackageReference&gt;\r\n<\/pre>\n<\/li>\n<li>Within the project root, i.e. where Program.cs is located, add a file tsconfig.json, mine looks like this\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;compilerOptions&quot;: {\r\n    &quot;module&quot;: &quot;ES2015&quot;,\r\n    &quot;target&quot;: &quot;ES2024&quot;,\r\n    &quot;sourceMap&quot;: true\r\n  },\r\n  &quot;exclude&quot;: &#x5B;\r\n    &quot;node_modules&quot;\r\n  ]\r\n}\r\n<\/pre>\n<\/li>\n<li>Let&#8217;s create a scripts folder off of wwwroot<\/li>\n<li>Now create a file, mine&#8217;s not very imaginatively named Example.ts and here&#8217;s the code\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nnamespace Example {\r\n    export class Prompt {\r\n        public showAlert(message: string): string {\r\n            return prompt(message, &quot;Hey&quot;);\r\n        }\r\n    }\r\n}\r\n\r\nexport function getPromptInstance(): Example.Prompt {\r\n    return new Example.Prompt();\r\n}\r\n<\/pre>\n<\/li>\n<\/ul>\n<p>Before we look at using this code let&#8217;s just review a few of the steps. <\/p>\n<p>The <em>tsconfig.json<\/em> if, ofcourse, used to configure the TypeScript transpiler. The <em>module<\/em> and <em>target<\/em> do NOT need to be these two values, but we do need to use a <em>module<\/em> type which will generate an export function. Some of the other module types will not include the export definition and then we cannot access the factory method <em>getPromptInstance<\/em>. So feel free to change these two options but before your JavaScript needs to export our factory function.<\/p>\n<p>As mentioned, we&#8217;re using the <em>getPromptInstance<\/em> to create an instance to our class, ofcourse we could export more functions and remove the class in this example. <\/p>\n<p><strong>Interop from Blazor<\/strong><\/p>\n<p>Interop. with our transpiled code uses the same mechanism\/code as my old post <a href=\"https:\/\/putridparrot.com\/blog\/blazor-and-the-javascript-interop\/\" target=\"_blank\">Blazor and the JavaScript interop.<\/a>, but let&#8217;s create some code in this sample anyway.<\/p>\n<p>Let&#8217;s do the following<\/p>\n<ul>\n<li>Add a Button to the Home.razor page that looks like this\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&lt;button class=&quot;btn btn-primary&quot; @onclick=&quot;DisplayMessage&quot;&gt;Alert me&lt;\/button&gt;\r\n<\/pre>\n<\/li>\n<li>Now add a code block which looks like this\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n@code{\r\n    private async Task DisplayMessage()\r\n    {\r\n        var module = await JsRuntime.InvokeAsync&lt;IJSObjectReference&gt;(&quot;import&quot;, &quot;.\/scripts\/Example.js&quot;);\r\n        var o = await module.InvokeAsync&lt;IJSObjectReference&gt;(&quot;getPromptInstance&quot;);\r\n        await o.InvokeVoidAsync(&quot;showAlert&quot;, &quot;Hello TypeScript World&quot;);\r\n    }\r\n}\r\n<\/pre>\n<\/li>\n<li>We also need to add the following to the top of the Home.razore file, below the @page line\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n@inject IJSRuntime JsRuntime\r\n<\/pre>\n<\/li>\n<\/ul>\n<p>Now when you run the application you&#8217;ll see the &#8220;Alert me&#8221; button, clicking this will load the script (note we reference the .js script here obviously) and then we get a reference to the <em>getPromptInstance<\/em> function and call the <em>showAlert<\/em> method of the previously defined TypeScript class.<\/p>\n<p>Obviously you&#8217;ll probably prefer to create a new C# class that holds onto a reference to the imported script, but hopefully this post gives you a starting point to porting\/using TypeScript code within your Blazor app.<\/p>\n<p>Code for this post is available at <a href=\"https:\/\/github.com\/putridparrot\/blog-projects\/tree\/master\/BlazorTypeScript\" target=\"_blank\">GitHub<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the past I wrote a blog post on Blazor and the JavaScript interop. but what about TypeScript, I mean it obviously transpiles to JavaScript, so we should be able to use it, right ? So yes, we can easily use TypeScript within a Blazor application, let&#8217;s do the following Create a Blazor WebAssembly Standalone [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[305,46],"tags":[],"class_list":["post-11141","post","type-post","status-publish","format-standard","hentry","category-blazor","category-typescript"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/11141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=11141"}],"version-history":[{"count":4,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/11141\/revisions"}],"predecessor-version":[{"id":11145,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/11141\/revisions\/11145"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=11141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=11141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=11141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}