One of the most common technology stacks right now for web applications is a backend code base on the .Net platform and written in C# and a frontend code base on a javascript-based platform written in Typescript. This technology stack along with other current technology stacks have presented a unique dichotomy of backend developers and frontend developers because of language and platform differences.
There is always a little bit of anxiety mixed with excitement around learning new languages, but the anxiety commonly leads to hesitancy from backend developers taking on the frontend development tasks and vice versa. This coding article will hopefully help ease the anxiety from these developers to transition into full-stack developers by showing how similar the main constructs are between C# and Typescript.
There are obviously other technology stacks and languages available to bridge gaps, so if you enjoy this article and would like similar articles written about other technology stacks, please comment below. This article will start with explaining why employers are searching for full-stack developers more than only frontend or backend developers, what is Typescript, what is C#, how some of the most common constructs are different and similar between Typescript and C#, and what steps should be taken to become a full-stack developer.
If you already know about Typescript and/or C# and would like to go straight into the construct differences between the two languages, please feel free to refer to the infographic I created below. Honestly, this amateur-ish infographic took me longer to create than I would like to admit (This is probably why I’m a developer instead of a graphic artist), so please download and share this infographic as much as you would like. If you want a deeper dive into Typescript or C#, I would recommend starting a free trial with Pluralsight, taking this C# course and this Typescript course on Udemy, or checking out this book on C# and this book on Typescript.
Why Employers Are Looking For More Full-Stack Devs
There are multiple benefits to being a full-stack developer for the developer and the employer. Being a full-stack developer means that debugging an issue is easier and faster because there is not as much ambiguity about how data is being transferred from the backend to the frontend and vice versa. This also limits the amount of effort it takes for discussions between frontend and backend developers. Conversation among a development team is not necessarily a bad thing, but it usually does cause troubleshooting to take longer than needed.
Full-stack developers are also not tied down to one platform, meaning that if one platform becomes more irrelevant to common development stacks, he or she still has an understanding of the other development stack. One example is with the common Javascript frameworks, there is really only a need for a database and a way to connect to the database to be a complete web application and with common frontend database technologies such as Pouchdb, backend technologies could hypothetically become somewhat irrelevant (I don’t necessarily believe this, but it could hypothetically happen).
If a developer is only familiar with backend technologies and the new common stack moves everything to the frontend, then it requires the developer to either try to find the few dev shops that still utilize the tech stack he or she is familiar with or abandon all current knowledge and learn the relevant technologies from scratch. This is obviously an extreme example, but there is no doubt that development technologies move fast, so platforms and languages can and will likely shift. Just as with any investment, diversifying knowledge across platforms and languages can help reduce the risk of a developer’s knowledge becoming outdated.
Employers find full-stack developers beneficial mainly for logistical reasons. For instance, if frontend development falls behind a milestone’s timeline estimation but the backend development is ahead of schedule, it is much easier for a manager to assign the frontend tasks to a full-stack developer on the current project so that domain knowledge around the project does not need to be transferred to a developer outside of the project. This also helps project managers with resource planning of new projects because there is more flexibility with which functionality in the scope can be assigned to a specific resource.
Personally, I find no reason why any developer should not take steps to become a full-stack developer if he or she has already proven he or she has what it takes to be a computer programmer. If you are purely a frontend or backend developer who has a firm understanding of Typescript or C#, hopefully, this comparison will be your first step to moving towards that full-stack path.
What Is Typescript?
Typescript is a ‘superset’ of Javascript, which means that syntactically-correct Javascript can be intermixed with the Typescript syntax. This is possible because Typescript is compiled into Javascript before being served onto any webpage. This makes Typescript uniquely different from other Javascript-based languages. Typescript is commonly used on both client-side and server-side stacks such as Node.js. Typescript is an open-source language that is developed and maintained by Microsoft and hosted on Github. Typescript supports many of the common features of most Object-Oriented Programming (OOP) language such as classes, interfaces, variables, modules, and more.
History
Typescript started being available in 2012 with version 0.8. Below is the introduction video of Typescript by Anders Hejlsberg during the release of Typescript. This version started the base of what Typescript is today with object-orient programming structures. The main issue after its’ initial release was the lack of IDE support. This was alleviated in future releases and support baked-in in version 1.0. Currently, Typescript is supported in IDEs such as Visual Studio, Atom, Sublime Text, Eclipse, Webstorm, and many others. Other versions have provided new features such as compilation speed increases, support for generics, new unknown types and many more. As of the writing of this article, the current version of Typescript is 3.1.
Why Should I Consider Typescript?
I think the best way to answer the question of why should anyone consider typescript with another question. Have you ever tried debugging Javascript? If you have, you know that unlike static-typed languages, Javascript is actually dynamically-typed which makes it very difficult to debug and forget about any intellisense arournd types in Javascript.
So, if you are familiar with statically-typed languages such as C#, you will likely have an easier time during development and more importantly during debugging than you would be using native Javascript. The other main reason anyone who is looking to become a full-stack developer should consider Typescript is its adoption rate. Because of the strongly-typed abilities and OOP principles Typescript follows, so many development teams are already using Typescript to impose the best development practices.
The main reasons why Typescript has seen better adoption rates than other languages such as CoffeeScript, Dart, and ScalaJS are that Typescript is a superset of Javascript instead of a replacement of Javascript and it is easier to learn for frontend developers who are already familiar with Javascript. Personally, there are very few frontend projects I have worked on where the Typescript package was not installed and utilized so I can say it is well worth the learning effort.
What Is C#?
C# is a strongly-typed and object-oriented programming language developed and maintained by Microsoft. C# was built as part of the .Net initiative to enhance the abilities and functionality of developers who are already familiar with C and C++ programming languages. C# was built to be flexible enough to develop minor web and desktop applications and be able to use when building advanced operating systems. C# provides common server-side language support such as automatic garbage collection, compilation checking, internationalization, type checking, and much more.
History
C# was released in the year of 2000 by a Microsoft team headed once again by Anders Hejlsberg. The intention of C# was to extend the capabilities of what C++ should have been. From the beginning, there was speculation of whether C# was intended as a copy of the Java programming language. As new versions of Java and C# were released, the differentiation between the two languages grew. As of the writing of this article, the latest version of C# is at version 7.3.
Why Should I Consider C#?
I spoke about why you should consider Typescript if you are a backend developer, so then why should you consider C# if you are a frontend developer? According to a 2018 survey on StackOverflow, about a third of development projects are using C#. Also, C# is a very sophisticated and mature language that provides great value to anyone looking to become experienced in backend development. Lastly, with Typescript and C# being developed by Microsoft under the same team leader, it makes sense to start learning C# if you are familiar with Typescript considering there will obviously be similarities between the two languages.
Typescript and C# Syntax Comparison
This section is not meant to be a fully comprehensive list of similar and different constructs between C# and Typescript, but it should provide enough to feel comfortable with building basic systems. As mentioned before, you can also look at and/or save the infographic above for a quick reference.
Types And Keywords
Many languages have many of the same types because they are the base of what any software program needs for basic functionality. Below are some of the most common types that Typescript and C# have and how each one maps.
Typescript Type/Keyword | C# Type/Keyword |
---|---|
String This represents any textual alphanumeric data. |
string This represents any textual alphanumeric data. The keyword ‘string’ is the C# alias for the .Net type of String. Either can be used. |
Number This represents any numeric data. |
int This represents any numeric data from -2,147,483,648 to 2,147,483,647. The keyword ‘int’ is the C# alias for the .Net type of Int32. Either can be used. There are also other signed types such as sbyte, short and long. The unsigned versions are byte, ushort, uint, and ulong. |
Boolean This represents any boolean true or false data. |
bool This represents any boolean true or false data. The keyword ‘bool’ is the C# alias for the .Net type of Boolean. Either can be used. |
Date This represents any date/time tracking data. |
Date/DateTime This represents any date/time tracking data. Date tracks only the date portion of a date of time whereas DateTime tracks the time along with the date. |
Boolean This represents any boolean true or false data. |
bool This represents any boolean true or false data. The keyword ‘bool’ is the C# alias for the .Net type of Boolean. Either can be used. |
Any This represents any generic data. |
Object This represents any generic data. Object is the base class for all C# types. |
Enum This represents static value types with a name and a value. |
Enum This represents static value types with a name and a value. |
Array This represents a fixed-size collection of same-type objects. |
Array This represents a fixed-size collection of same-type objects. |
Null This represents the absence of any value. This is different from the traditional undefined value in Javascript. Undefined means a variable is declared, but not assigned whereas null is an assigned value. Undefined is a type while null is an object. |
null This represents a literal that is a null reference. Null is the default value of reference-type variables. |
Tuple This represents an array, with mixed types and a limited number of items. |
Tuple This represents a data structure that contains a sequence of elements of different data types. Tuples are available in .Net 4.0 and later |
Void This represents the return of a function that does not return a value. Assigning void as a type for a variable would make no sense because you could only assign undefined or null to the variable. |
void This represents the return of a method that does not return a value. |
Const This represents a keyword that prevents re-assignment of a variable. |
const This represents an immutable value that cannot change for the life of the program. |
With every type in both languages, every type can be Nullable with the addition of a question mark. We will get into Nullable types a little later.
Variables
Typescript variables start with the keyword ‘let’ followed by the name of the variable and finally a colon along with the type of variable. The type of ‘var’ can be used in either Typescript or C# but is not best practice. C# starts with the type followed by the name of the variable. Unlike Typescript, C# must always have the type explicitly defined. Below are examples of variable declarations from both languages.
Variables – Typescript
[code lang=’javascript’]
let name:string = ”mary”;
let name:string;
let name = “mary”;
let name;
[/code]
Variables – C#
[code lang=’csharp’]
string name = ”mary”;
string name;
[/code]
Loops
For Loop – Typescript
[code lang=’javascript’]
for (let i in list) {
console.log(i);
}
for (let i of list) {
console.log(i);
}
[/code]
The ‘in’ for loop returns the index of each iteration in the variable set as ‘i’. The ‘of’ for loop returns the value of each iteration in the variable set as ‘i’. In C# this Typescript for loop seems similar to the way a foreach loop is created.
For Loop – C#
[code lang=’csharp’]
for (int i = 0; i < offset; i++)
{
Console.WriteLine(i);
Console.WriteLine(list[i]);
}
[/code]
In C#, the variable called 'i' is the index of the item in the loop. Unlike Typescript, the variable 'i' is declared with an initial value, the condition is set with a conditional to know how when to exit the loop, and lastly, the variable 'i' is incremented or decremented by a set number.
ForEach Loop – Typescript
[code lang=’javascript’]
let command:string[]=[];
command = [“Save”,”This”,”Image”];
command.forEach(com => console.log(com + ” “));
[/code]
The foreach iterator is a method on the array object to iterate through items. In the example above, the array called ‘command’ is iterated over through a forEach loop with the generic variable being called ‘com’.
ForEach Loop – C#
[code lang=’csharp’]
List command = new List()
{
“Save”, “This”, “Image”
};
foreach (string com in command)
{
Console.WriteLine(com + ” “);
}
[/code]
OR
[code lang=’csharp’]
List command = new List()
{
“Save”, “This”, “Image”
};
command.ForEach(com => Console.WriteLine(com + ” “));
[/code]
OR
[code lang=’csharp’]
string[] command = {“Save”, “This”, “Image”};
Array.ForEach(command, com => Console.WriteLine(com + ” “));
[/code]
The first foreach loop allows iterating over arrays, lists, etc. It is The second foreach loop DOES NOT allow iterating over arrays because it is a lambda expression on the List, but the third foreach loop will allow iterating over an array.
While Loop – Typescript
[code lang=’javascript’]
let n:number = 1;
while(n < 5) {
n = n + 1;
}
[/code]
In the code above and below, the variable, n, is set to one and while the variable is less than one, the while loop will execute the logic inside to add one to the variable n. The logic is run only while the equality statement is true and is not executed if the expression is not true.
While Loop – C#
[code lang=’csharp’]
int n = 1;
while (n < 5)
{
n++;
}
[/code]
Do While Loop – Typescript
[code lang=’javascript’]
let n:number = 1;
do {
n = n + 1;
}
while(n<5);
[/code]
The do while loop above and below causes the logic inside of the loop to run before the while logic is considered. Once the while loop expression evaluates to false, the execution will jump out of the loop.
Do While Loop – C#
[code lang=’csharp’]
int n = 1;
do {
n++;
}
while(n<5);
[/code]
Conditionals
If-Else Conditional – Typescript
[code lang=’javascript’]
let num:number = 2;
if(num > 0) {
console.log(num+” is positive”)
} else if(num < 0) {
console.log(num+" is negative")
} else {
console.log(num+" is neither positive nor negative")
}
[/code]
The if-else conditional block above and below are essentially the same. Each if statement and if-else statement have conditional statements to determine whether to jump into the code block. The last step is the else block if the logic skips the if and else-if logic.
If-Else Conditional – C#
[code lang=’csharp’]
int num = 2;
if(num > 0)
{
Console.WriteLine(num+” is positive”)
}
else if(num < 0)
{
Console.WriteLine(num+" is negative")
}
else
{
Console.WriteLine(num+" is neither positive nor negative")
}
[/code]
Switch Statement – Typescript
[code lang=’javascript’]
let grade: string = “A”;
switch (grade)
{
case’A’:
console.log(‘A’);
break;
case’B’:
console.log(‘B’);
break;
case’C’:
console.log(‘C’);
break;
case’D’:
console.log(‘D’);
break;
default:
console.log(‘F’);
break;
}
[/code]
In the switch statements above and below both have multiple case statements within the switch statement and a final default if none of the case statments match the switch parameter. The keywords ‘continue’ and ‘break’ can be used in both language’s switch statements.
Switch Statement – C#
[code lang=’csharp’]
string grade = “A”;
switch (grade)
{
case “A”:
Console.WriteLine(“A”);
break;
case’B’:
Console.WriteLine(“B”);
break;
case’C’:
Console.WriteLine(“C”);
break;
case’D’:
Console.WriteLine(“D”);
break;
default:
Console.WriteLine(“F”);
break;
}
[/code]
Interfaces
Interface – Typescript
[code lang=’javascript’]
interface IButton extends ISelectableControl, Control {
Text: string;
}
[/code]
Interfaces in Typescript provide structure to objects. Interfaces can inherit from other interfaces and classes. All members in an interface must be implemented within any class extending the interface. In the example above, the interface of IButton is inheriting from another interface called ISelectableControl and a class called Control. The extends keyword is used to denote inheritance.
Interface – C#
[code lang=’csharp’]
interface IButton: ISelectableControl, IControl
{
string Text {get; set;}
}
[/code]
Interfaces are contracts for classes to implement, Interfaces can ONLY inherit from other interfaces in C#. In the example above, the interface of IButton is inheriting from another interface called ISelectableControl and another interface called IControl. The colon is used to denote inheritance. The ‘I’ at the beginning of the interface name is not required but is considered a best naming practice for interfaces to distinguish from classes.
Classes
Class – Typescript
[code lang=’javascript’]
class Lamp extends Light implements IDecor, IStuff {
Color: string;
DimmerType: string = ‘pull down’;
constructor(size: string) {
super(size);
}
}
[/code]
In Typescript, classes use the ‘extends’ keyword for base classes and the ‘implements’ keyword is used when a class implements an interface. A class’s constructor is denoted by the ‘constructor’ keyword. The ‘super’ keyword is used to call the base constructor. In the example above, the class of Lamp extends the class called Light and implements the interfaces called IDecor and IStuff.
Class – Typescript
[code lang=’csharp’]
public class Lamp : Light, IDecor, IStuff {
public string Color {get; set;};
private string DimmerType = “pull down”;
Lamp(string size) : base(size) {
}
}
[/code]
In C#, classes use the colon for base classes and when a class implements an interface. A class’s constructor is denoted by the same name as the class with no modifier and no return type. The ‘base’ keyword is used to call the base constructor. In the example above, the class of Lamp extends the class called Light and implements the interfaces called IDecor and IStuff.
Functions/Methods
Function – Typescript
[code lang=’javascript’]
create(msg: String, logDate?: Date) : boolean {
return true;
}
[/code]
In Typescript, the default access modifier for functions is public. The available access modifiers are public, protected, private, and static. Just as with declaring variables, the parameter name is declared first followed by a colon and then the type. Optional parameters are denoted by a question mark at the end of the parameter’s name. The return type of the function is set by a colon followed by the type. An example is shown above.
Method – C#
[code lang=’csharp’]
public bool create(string msg, DateTime? logDate)
{
return true;
}
[/code]
In C#, the default access modifier for methods is private. The available access modifiers are public, protected, private, internal and protected internal. Just as with declaring variables, the access modifier is set first followed by the return type of the method and then the method name. Each parameter type is declared first followed by the parameter name. Optional parameters are denoted by a question mark at the end of the parameter’s type. An example is shown above.
Filtering
Filters – Typescript
[code lang=’javascript’]
// similar to C# Where filter
let selectedresources = resources.filter(x => x.documentcategory === this.selectedcategory);
// similar to C# Any filter
boolean found = (resources.findIndex(x => x.documentcategory === this.selectedcategory) >= 0);
// similar to C# FirstOrDefault filter
let firstresource = resources.find(x => x.documentcategory === this.selectedcategory);
[/code]
The function called ‘filter’ filters the array based on the predicate statement. This is similar to a ‘Where’ lambda function in C#. The function called ‘findIndex’ returns -1 if nothing is found based on the predicate and zero or higher if the predicate is found. This is similar to the ‘Any’ lambda function in C#. The ‘find’ function searches the array and returns the first item matching the predicate statement. This is similar to the FirstOrDefault lambda function.
Filters – C#
[code lang=’csharp’]
// similar to Typescript filter filter
List selectedresources = resources.Where(x => x.documentcategory == this.selectedcategory);
// similar to Typescript findIndex filter
bool found = resources.Any(x => x.documentcategory == this.selectedcategory);
// similar to Typescript find filter
resource firstresource = resources.FirstOrDefault(x => x.documentcategory == this.selectedcategory);
[/code]
The lambda function called ‘Where’ filters the list based on the predicate statement. This is similar to the ‘filter’ function in Typescript. The lambda function called ‘Any’ returns false if nothing is found based on the predicate and true if the predicate is found. This is similar to the ‘findIndex’ function in Typescript. The ‘FirstOrDefault’ lambda function searches the list and returns the first item matching the predicate statement or null if nothing is found. This is similar to the ‘find’ function.
Final Thoughts
Hopefully, this article helped you to understand more about Typescript if you are a backend developer, helped you to understand more about C# if you are a frontend developer, or simply provided a healthy respect for the importance of being a full-stack developer. As you probably noticed by reviewing the syntax of Typescript and C# above that they are actually not that different, so if you are on the fence or hesitant about going full-stack, learning Typescript from C# or learning C# from Typescript is not that scary.
As mentioned in the beginning, if you want a deeper dive into Typescript or C#, I would recommend starting a free trial with Pluralsight, taking this C# course and this Typescript course on Udemy, or checking out this book on C# and this book on Typescript. As I mentioned before, please feel free to download and share this infographic above as much as you would like. If you would like more articles like this with different languages, please comment below.
If you enjoy this blog’s content and would like to help out a developer or computer science student, feel free to
If you like the shirt below, you can view more about how to get it here.
This is a very informative post and would help many to take their coding skills to another level. Thanks for sharing and explaining it so well. It’s very helpful!