Typescript Basics

Lance Watanabe
5 min readNov 4, 2021

Javascript is a great language. Javascript is a loosely typed language which means sometimes when we pass arguments into functions or access/set properties on objects, Javascript does not throw an error. Typescript seeks to solve this issue using a strongly-typed approach. Typescript is built on top of Javascript (Typescript compiles to Javascript). When declaring a variable, we set the type so that if the variable is updated, the new value must match the type. Similarly, we declare the type of the parameters for functions so that we don’t pass in incorrect arguments. Additionally, we define the expected return type. Although these approaches call for more code, it will result is catching more bugs. In addition, it will result in better understanding of the code as the reader will be able to see the type of each argument and the return values.

  • Primitive Types: You can declare a variable with an explicit type of number, string, boolean, or any (it could be any type)
let id: number = 5
let company: string = 'mcdonalds'
let isAlive: boolean = true
let x: any = 'Hello'
  • Arrays: We specify that each element in numberArray is a “number” and booleanArray is “boolean.”
let numberArray: number[] = [1, 2, 3, 4]
let booleanArray: boolean[] = [true, false, false]
  • Objects / Interfaces: We create an interface object that mirrors the structure of the “hostUser” object.
interface User {
id: number
name: string
}
const hostUser: User = {
id: 2,
name: 'john'
}
  • Type Keyword: Interfaces are used for complex types but cannot be used for primitive types. Instead, you must use the “type” keyword.
type CoordinateType = number
const myCoordinate: CoordinateType = 55
  • Parameter Types in Functions: If the function expects arguments, you must specify the types of all of the arguments. The function below expects an object argument with a name and id parameters. We declare an interface to represent the object that we expect to pass into the function.
interface User {
name: string;
id: number;
}
function deleteUser(user: User) {
return user.id && user.name
}
  • Return Value Types in Functions: In the function below, we specify the return type using the User interface. As you can see, the return object matches the User interface. Note, it is not necessary to define the return value. It is just better for documentation sake.
interface User {
name: string;
id: number;
}
function getAdminUser(): User {
return {
name: 'lebron',
id: 23
}
}
  • No Return Value in a Function: If the function does not return anything, we should set the return type to “void.”
function sayHello(): void {
console.log('hello')
}
  • Type Assertion: When a type is declared as “any,” if a new variable references the original variable, we can specify the type.
let playerNumber: any = 1
let startingPlayer = <number>playerNumber
let benchPlayer = playerNumber as number
  • Generics: Sometimes, we write functions that will accept different argument types. The types of the arguments will be determined when the function is called. Therefore, we use a generic parameter to represent the type. In the example below, we have a generic type called <T>. When we call myFunction() the first time, we set the generic type to <string>. When we call myFunction() the second time, we set the generic type to <number>.
function myFunction<T>(arg: T): T {
return arg;
}
let stringArgument = myFunction<string>("myString");
let numberArgument = myFunction<number>(44);
  • Generic Arrays with Functions: The getArrayWithGenerics function uses a <Type> generic. The function expects a parameter called “items” with a type of an array with each element of type “T.” The function specifies that it will return an array with each element of type “T.” When getArrayWithGenerics is called the first time, we set the generic to <number> which means we are passing in an array of “numbers” and the function will return an array of “numbers.” Similarly, when getArrayWithGenerics is called the second time, we set the generic to <string> which means we are passing in an array of “strings” and the function will return an array of “strings.”
function getArrayWithGenerics<T>(items: T[]): T[] {
return new Array().concat(items)
}
let numberArray = getArrayWithGenerics<number>([1, 2, 3, 4])
let stringArray = getArrayWithGenerics<string>(['a', 'b', 'c', 'd'])
  • Generics in Interfaces: In the example below, we define an interface called Tab. We have a generic called <T>. We can utilize this generic for the type of the “data” property. When we use the Tab interface, we set the value of the generic to <number>. Therefore, the type of the “data” property becomes “number.”
interface Tab <T> {
id: string;
position: number;
data: T; //number
}
type numberTab = Tab<number>
  • Multiple Generics: We can use multiple generics <T, Y> as shown below. We can use each generic to set the types of the parameters or return values. We set the value of the generic when we call the function <string, string>
const makeArray = <T, Y>(x:T, y: Y): [T, Y] => { 
return [x, y]
}
const v5 = makeArr2<string, string>('a', 'b')
  • Generics Default Value: We can set the default type to “number” when we define the function. We can override the default value when we call the function and set the generic to “string.”
function myFunction<T = number>(arg: T): T {
return arg;
}
let stringArgument = myFunction<string>("myString");
  • “Declare” a module: You can create a module that can be exported using the “declare” keyword.
declare module "foo-module" {
function foo(): void;
export = foo;
}
// import foo in another file
import foo from "foo-module";
foo();
  • Interface merging: Typescript will merge interfaces with the same name.
interface Box {
height: number;
width: number;
}
interface Box {
scale: number;
}
let box: Box = { height: 5, width: 6, scale: 10 };
  • Parameter types: You can specify the types of the arguments you expect to be passed into the function.
const printInnerFunction = (testString: string) => {
console.log(testString)
}
  • Optional Parameters: Sometimes, you may not know if the argument will be passed in so you can simply tell Typescript that the parameter is optional
const printInnerFunction = (testString?: string) => {
console.log(testString)
}
  • Optional Function Parameters: If you have an optional function parameter, Typescript may throw an error if you try to call that function (callback function). Typescript will assume the worst case scenario that the callback function is not passed into the function so the argument will be “undefined” and Typescript doesn’t know what to do if you try to call “undefined.” Instead, you can resolve this problem by checking if the callback function was passed in before calling it.
const printInnerFunction = (testString: string) => {
console.log(testString)
}
const printOuterFunction = (printFunc?: ()=>void) => {
printFunc && printFunc()
}

--

--