Creating Own Types In Typescript
Tags: webdev, beginners, typescript, tutorial
Published: 2022-10-08 21:40:30

##Enum
An enumeration is a type that represents named constants and is often refered to as an enum. It can be very good if meaning of constant value is'nt apparent, this can make the code easier to understand.
```ts
enum Response{
     Ok = 200,
     Error = 400
}

if (status === 200) {
  // do something
}

if (status === Response.Ok) {
  // do something
}

```
The problem with this approach is reflected exactly in numerical enums that are weakly-typed, although string enum are strongly-typed.
```ts
enum Level {
  High,
  Medium,
  Low
}
level = 5; // no error accur


enum Level {
  High = "H",
  Medium = "M",
  Low = "L"
}
level = "VH"; // a type error occur

```
##Object Types
In first typescript has a good inferred types system for objects. When  hovering the mouse over object you will see the type inferred to object and if you try to change a property to a value of a different type or try to add a property that there are'nt it will return an error.
```ts
const JackScore = {
  name: "Jack",
  score: 70
};

JackScore.score = 75; // no error accur
JackScore.score = 'test'; // a type error occur
JackScore.passed = true; // a type error occur
```
There is also an explicit way to type objects and it has the same strength.
```ts
const JackScore: { name: string; score: number; }  = {
  name: "Jack",
  score: 70
};

JackScore.score = 75; // no error accur
JackScore.score = 'test'; // a type error occur
JackScore.passed = true; // a type error occur
```
The both ways are strongly-typed, although if you wish reuse an object type could be tiring redefinning it each time and that's why type aliases and interfaces is so important. 
##Type Aliases and Interfaces
Type aliases and interfaces are ways of reuse your types and make typing process faster.
```ts
//without types alias and interfaces
const tomScore: { name: string; score: number } = {
  name: "Tom",
  score: 70,
};
const bobScore: { name: string; score: number } = {
  name: "Bob",
  score: 80,
};
const janeScore: { name: string; score: number } = {
  name: "Jane",
  score: 90,
};
//with types alias and interfaces
type Score = {            interface Score {
name:string,       or     name:string,
score:number              score:number
}                        }

const tomScore: Score = { name: "Tom", score: 70 };
const bobScore: Score = { name: "Bob", score: 80 };
const janeScore: Score = { name: "Jane", score: 90 };

```
##What's difference between interface and type alias
###Representing primitive types
Type aliases can represent primitive types, but interfaces can't.
```ts
type Name = string;
```
###Representing arrays
Both reprensent arrays, although type alias approach is a lot more concise and clearer.
```ts
type Names = string[];

interface Names {
  [index: number]: string;
}
```
###Representing tuples
Type aliases can represent tuples types, interfaces can't
```ts
type Point = [number, number];
}
```
###Representing functions
Both can represent functions, but type alias is a lot more concise and clearer.
```ts
type Log = (message: string) => void;

interface Log {
  (message: string): void;
}
```
###Creating union types
Only type aliases can represent union types. 
```ts
type Status = "pending" | "working" | "complete";
```
###Representing objects
both can represent types of an object and even the type alias being the most concise approach the equals operator (=) can result in the statement being confused for a variable assignment to an object literal.
We can say that there is a tie here.
```ts
type Person = {
  name: string;
  score: number;
};

interface Person {
  name: string;
  score: number;
}
```
###Composing objects
Type aliases and interfaces can both compose objects together.
```ts
type Name = {
  firstName: string;
  lastName: string;
};
type PhoneNumber = {
  landline: string;
  mobile: string;
};
type Contact = Name & PhoneNumber;

interface Name {
  firstName: string;
  lastName: string;
}
interface PhoneNumber {
  landline: string;
  mobile: string;
}
interface Contact extends Name, PhoneNumber {}
```
###Authoring a library
One important feature that interfaces have that type aliases don't is declaration merging:
```ts
interface ButtonProps {
  text: string;
  onClick: () => void;
}
interface ButtonProps {
  id: string;
}
```
This is is useful for adding missing type information on 3rd party libraries. If you are authoring a library and want to allow this capability, then interfaces are the only way to go.