Using TypeScript in .cshtml Razor Files

Recently, I embarked on a new project utilizing the ASP.NET-MVC framework. For this particular project, I decided to opt for TypeScript over JavaScript. While Visual Studio provides excellent support for TypeScript, I encountered some compatibility issues when integrating it with .cshtml razor files. Although I could define and utilize classes in my .ts file and call them within the .cshtml file, I faced challenges when passing parameters to objects in the .cshtml file where TypeSafety seemed to be disregarded.

.ts file

export class SomeClass {

    name: number;

    constructor(public tName: number) {
        this.name = tName;
    }

    public sayName() {
        alert(this.name);
    }
}

.cshtml file

var instance = new SomeClass("Timmy");
instance.sayName();

In the above code snippet, I unintentionally passed a string to the constructor despite specifying that only numbers should be accepted as parameters. This caused TypeSafety to be overlooked, leading to the execution of TypeScript/JavaScript without error prompts.

Considering both file types are developed by Microsoft, I found it slightly surprising that they do not seamlessly integrate with each other. Nevertheless, while this issue is not insurmountable and allows me to continue leveraging Object Oriented Programming principles, I am interested to hear from others who may have encountered similar challenges and seek input or insights on this matter.

Answer №1

When using a TypeScript transpiler, it will only check and transpile files that exclusively contain:

  • Javascript code
  • Javascript with additional syntax sugar provided by TypeScript (such as static typing, generic classes, etc.)

CSHTML files are primarily designed to include Razor/C# code along with HTML/JavaScript/CSS elements.

Although some developers try to insert JavaScript code and CSS stylesheets directly into CSHTML files, this is considered a poor practice.

It is recommended to keep JavaScript code and CSS styles in separate files, and then reference them using the script tag for JavaScript or style tag for CSS within your CSHTML file.

Directly embedding JavaScript code in your view (whether it's CSHTML or just HTML) goes against the principles of Unobtrusive JavaScript:

The principle of separating functionality (the "behavior layer") from a Web page's structure/content and presentation (source: Wikipedia)

Some ASP.Net MVC developers persist in placing JavaScript code directly in their Razor views because they need to pass data from the view model to the JavaScript seamlessly. However, this approach is discouraged ;-).

To adhere to Unobtrusive JavaScript principles, all data required by JavaScript should be stored using data attributes within HTML elements:

<span id="mySpan" data-t-name="123456">Hello World</span>

In your TypeScript code, simply utilize jQuery (or vanilla JavaScript) to retrieve the data set in your CSHTML view like so:

let tName: number = parseInt($("#mySpan").data("t-name"));
var instance = new SomeClass(tName);
instance.sayName();

Finally, ensure to reference the generated JavaScript file from TypeScript in your CSHTML file.

I hope this explanation proves helpful!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide to simulating ngControl in a Custom Form Control for effective unit testing in Angular

I need some guidance on creating unit tests for a Custom Form Control in Angular 9. The issue arises with this line of code: constructor(@Self() private ngControl: NgControl), which triggers an error: Error: NodeInjector: NOT_FOUND [NgControl]. It seems th ...

Encountering a Nuxt error where properties of null are being attempted to be read, specifically the 'addEventListener' property. As a result, both the default

Currently, I am utilizing nuxt.js along with vuesax as my UI framework. I made particular adjustments to my default.vue file located in the /layouts directory by incorporating a basic navbar template example from vuesax. Subsequently, I employed @nuxtjs/ ...

What is the best way to set up the parser and plugins using ESLint's updated flat configuration?

How can ESLint be configured using the new "flat config" system (specifically with the eslint.config.js file) to work seamlessly with both @typescript-eslint/eslint-plugin and /parser? I have been struggling to make ESLint's new configuration system ...

What is the process for retrieving mouse windows messages from outside of an application?

Apologies in advance if this question seems too specific to C#, but I couldn't find information on this topic for VB.NET and my understanding of C# is limited. Essentially, my goal is to capture and process mouse messages from outside the application ...

Tips for utilizing mergeWith with Subjects in an Angular application

Objective: Creating a Combined Filter with 3 Inputs to refine a list Conditions: Users are not required to complete all filters before submission The first submit occurs when the user inputs data Inputs are combined after more than one is provided Appro ...

What could be causing the primeng dialog to appear blank when conducting Jasmine tests on this Angular TypeScript application?

Having trouble testing a component due to rendering issues? Check out the code snippet below: import {ChangeDetectionStrategy, Component, EventEmitter, Input, Output} from '@angular/core'; @Component({ selector: 'app-help', cha ...

Remove the Prisma self-referencing relationship (one-to-many)

I'm working with this particular prisma schema: model Directory { id String @id @default(cuid()) name String? parentDirectoryId String? userId String parentDirectory Directory? @relation("p ...

Output Scalable Vector Graphics (SVG) content on a webpage

I need to include an SVG element in my Angular 2+ code. My goal is to provide users with the option to print the SVG element as it appears on the screen. <div class="floor-plan" id="printSectionId2" (drop)="onDrop($event)" (dragover)="onDragOver ...

Resolve the Typescript issue that occurs while modifying MuiDataGrid within createTheme

I am trying to customize my DataGridPro table, which is a MUI component, within the theme. However, when I add MuiDataGrid to the components object, I encounter a TypeScript error: Object literal may only specify known properties, and 'MuiDataGrid&apo ...

Customizing MUI V5 Variants

I'm having trouble customizing the variant options in MUIPaper, and I can't figure out what mistake I'm making. The available types for the component are: variant?: OverridableStringUnion<'elevation' | 'outlined', Pape ...

Updating the Likes count for a particular page using SignalR in MVC: A step-by-step guide

Having trouble with SignalR implementation in my MVC application. Whenever a user clicks the like button on a specific album post page, the likes count for all other pages gets updated as well. Here is the code for my NotificationHub: public class Notific ...

The efficiency of React Context API's setters is remarkably sluggish

I have a goal to implement a functionality where the background gradient of a page changes depending on whether the child's sublinks are expanded or collapsed. To achieve this, I am using the useContext hook. However, I've noticed that although e ...

Is it possible to use the HostListener in Angular 7 to detect any scroll event occurring on a specific element within a webpage?

I am developing a breadcrumb bar component in Angular 7 that should dynamically hide and show based on user scrolling behavior. To achieve this, I created a directive to track the scroll position of the container element. While my code for capturing the s ...

What is the process for integrating a tensorflow.js model into a React-based web application?

I've been working on a React web application in Typescript that involves loading a tensorflow.js model and then applying it each time the component updates. While I successfully implemented this in a small demo app without React, I am facing some chal ...

Props used in styled components are effective, although they may trigger a warning message stating, "Warning: Received `true` for a non-boolean attribute `cen`."

Caution: A non-boolean attribute "cen" received a value of "true". If you intend to render it in the DOM, provide a string instead: cen="true" or cen={value.toString()}. While using Props in Styled-Component with TypeScript and Material-UI, everything func ...

The 'palette' property is not found on the Type 'Theme' within the MUI Property

Having some trouble with MUI and TypeScript. I keep encountering this error message: Property 'palette' does not exist on type 'Theme'.ts(2339) Check out the code snippet below: const StyledTextField = styled(TextField)(({ theme }) = ...

Exploring the possibilities of developing WebComponents within Angular using TypeScript

My Angular application was originally created using the default method with ng new project-name". However, for performance reasons, I had to incorporate single standard WebComponents. The JavaScript code associated with these components is stored in a ...

Ways to retrieve a variable from a separate TypeScript document

A scenario arises where a TypeScript script contains a variable called enlightenFilters$: import { Component, Input, OnInit } from "@angular/core"; import { ConfigType, LisaConfig } from "app/enrichment/models/lisa/configuration.model"; ...

What steps should be taken to enable SCSS in Jest for unit testing in TypeScript Next.js?

I am facing an issue with the scss import in my project. I have attempted to solve it by using mockup and identity-obj-proxy, but neither of them seems to work. I suspect that there might be a problem with my regex expression. The specific error arises fr ...

Wrapper around union function in TypeScript with generics

I'm struggling to find a solution for typing a wrapper function. My goal is to enhance a form control's onChange callback by adding a console.log. Can someone please point out what I might be overlooking? interface TextInput { type: 'Tex ...