declaring variable (explicit)
let username: string = 'Janet Austin';
declaring variable (implicit)
declaring variable implicit is just like writing JavaScript
let firstname = 'jane';
in this case (implicit), typescript guess the type of data firstname is. Having TypeScript "guess" the type of a value is called infer.
Error in re assignment
let myName : string = 'janet';
myName = 30;
//Type 'number' is not assignable to type 'string'.ts(2322)
javascript would not give such error if a varable is assign to a value of different type.
TypeScript may not properly infer what the type of a variable is. In such cases, it will set the type to any which will disable type checking.
Special types
there are four special types
1. any
any is a type that disables type checking and effectively allows all types to be used.
let x : any = 'boy';
x = 7
the code above does not have an error even though the variable was first assigned to string and later re assigned to number. this is because the type check has been disable by any.
2. unknown
unknown is a similar, but a safer alternative to any.
let age: unknown = 1;
console.log(age)
//Error:'age' is of type 'unknown'.ts(18046)
const person: unknown = {
firstname:'sara',
age:25
}
console.log(person.age)
//Error:'person' is of type 'unknown'.ts(18046)
TypeScript will prevent unknown types from being used, the variable age and the object person, cannot be use in our code because their type is explicit unknown. We have to narrow or case the unknown type before we can use it.
Narrowing
let age: unknown = 1;
if (typeof age === 'number') {
//we can now use age in our code without getting any error
console.log(age)
}
Casing
const person: unknown = {
firstname:'sara',
age:25
}
console.log((person as{age:number}))
age in the object person was given a specific type before person can be use
3. Never
never throws an error whenever it is defined.
let i: never = true;
// Error: Type 'boolean' is not assignable to type 'never'.
4. Underfine & Null
undefined and null are types that refer to the JavaScript primitives undefined and null respectively.
let q: undefined = undefined;
let z: null = null;
Array
const array: string[] = [];
array.push('john');
array.push(9)//Error: Argument of type 'number' is not assignable to parameter of type 'string'
const names: number[] = [];
names.push(5);
names.push(3);
The readonly keyword can prevent arrays from being changed.
const firstname: readonly string[] = ["Emeka"];
surname.push("Jack");
//Error: Property 'push' does not exist on type 'readonly string[]'.
TypeScript can infer the type of an array if it has values.
const numbers = [1, 2, 3]; // inferred to type number[]
numbers.push(4);
Tuples
A tuple is a typed array with a pre-defined length and types for each index.
let tuple : [string, boolean, number];
tuple = ['hello world', true, 5];
Always ensure your type correspond to your value, else there will be an error as seen below
let tuple : [string, boolean, number];
tuple = [8, 'hello', false]
//Type 'string' is not assignable to type 'boolean'.ts(2322)
//Type 'boolean' is not assignable to type 'number'.ts(2322)
//Type 'number' is not assignable to type 'string'.ts(2322)
it is advisable to also make your tuple readonly, because more values can be added to it and there is not type safety for these now values.
let tuple : [string, boolean, number];
tuple = ['hello world', true, 5];
tuple.push('hello again')
a new value was push to the tuple as seen above, the new value can be anything since there's no type safety.
const tuple: readonly [number, boolean, string] = [5, true, 'i love typescript'];
tuple.push('hi')*
//Property 'push' does not exist on type 'readonly [number, boolean, string]'.ts(2339)
the above code gives an error because the tuple is now readonly, so we can push a new value to the tuple
Named Tuples
Named tuples allow us to provide context for our values at each index.
const person: [age: number, pet: string] = [29, 'dog'];
Destructuring Tuples
tuples are arrays so we can destructure them
let info:[string, number] = ["hello",7];
const [valueOne,valueTwo] = info;
console.log(valueOne)//hello
typescrip object
const house :{ type:string,year:number} = {
type:'mansion',
year:1678
}
TypeScript can infer the types of properties based on their values.
const person = {
name:'Efe'
}
//person.name is infer to as a string
optional index in object
const car: { type: string, mileage: number } = {
type: "Toyota",
};
car.mileage = 2000;
// Error: Property 'mileage' is missing in type '{ type: string; }' but required in type '{ type: string; mileage: number; }'.
to make an optional index, we use the ? sign as seen below
const car: { type: string, mileage?: number } = {
type: "Toyota"
};
car3.mileage = 2000;
Index signatures can be used for objects without a defined list of properties.
const Age: { [index: string]: number } = {};
Age.Paul = 25;
Age.Karo = "Fifty";
// Error: Type 'string' is not assignable to type 'number'.
Enums
An enum is a special "class" that represents a group of constants (unchangeable variables).
Enums come in two flavors string and numeric. Lets start with numeric.
enum Shapes {
Square,
Triangle,
Rectangle
}
console.log(Shapes.Square)//returns 0
//plus 1 is added to the remaining value
console.log(Shapes.Rectangle)//returns 2
enum Shapes {
Square = 1,
Triangle,
Rectangle
}
console.log(Shapes.Square)//returns 1
//plus 1 is added to the remaining value
console.log(Shapes.Rectangle)//returns 3
each value can also be assign parmanent number or string
enum response {
success = 200,
redirect = 300,
NotFound = 404,
}
enum CardinalDirection {
North = 'North',
East = "East",
South = "South",
West = "West"
};
Type Aliases and Interfaces
TypeScript allows types to be defined separately from the variables that use them.
Aliases and Interfaces allows types to be shared between different variables and objects easily.
Type Aliases
Type Aliases allow defining types with a custom name (an Alias).
Type Aliases can be used for primitives like string or more complex types such as objects and arrays:
type year = number;
type model = string;
type data = {
theYear:year,
theModel:model
}
const realVal : data = {
theYear:2003,
theModel:'masion'
}
Interfaces
Interfaces are similar to type aliases, except they only apply to object types.
interface Person {
age: number,
surName: string
}
const person: Person = {
age: 20,
surName: 'Johnsons'
};
Extending Interfaces
To extend an interface means you are creating a new interface with the same properties as the original.
interface Animal {
name: string
}
interface Bird extends Animal {
sound:string
}
const Animal: Bird = {
name:'Parrot',
sound:'squawk'
}
Union | (OR)
Union are use on value with more than one types.
Such as when a property would be string or number.
Using the | we are saying our parameter is a string or number
let age:string | number
age can be a string or a number and there will be no type error
Union Type Errors
Note: you need to know what your type is when union types are being used to avoid type errors:
let code: string | number = 7
console.log(code.toUpperCase())
// Property 'toUpperCase' does not exist on type 'number'
// error: Property 'toUpperCase' does not exist ontype 'string | number'.
In our example we are having an issue invoking toUpperCase() as its a string method and number doesn't have access to it.
these are some basic you need to know to enable you become a type script developer, part 2 loading soon.
Top comments (0)