Hi :wave:, I am back again with new article, read the previous article from here if you did not yet and grab a cub of coffee, tea or whatever you like and let's start In the previous article we have had an overview about typescript compiling and how the syntax looks likes. Here we are going to look in some thing very critical in typescript ; types. An oversimplified description of typescript would be javascript in addtion to types, of course there are more in typescript by types is the core point. We are going to talk about
- Why to use types
- Basic types
- Never and void types
- Literal types I found this interested one
- Object types
and more ...
Javascript is weekly typed language this means the type of variable is figure by the js in runtime. and can change from one type to another.
let x = 6 // JS: ah, this a Number
let y = 12/6 // JS: ok, this equals to 2 then y is also a Number
x = "I can be string" //JS: Now x is string np
You may consider this as a feature but under some consequences when we are using apis or working over multiple files with other developers this may cause a severe headache. Suppose our friend Hossam wrote this simple function that adds tax value :
export default const addTax = p => p*1.14
Now we imported it and going to use it
const shoppingIist = [2,1,undefined,10]
const prices = shoppinglist.map(p=>addTax(p)) // [2.28,1.14,NaN,11.4] NaN?
however this is simple bug it won't be discovered until the runtime. Let's now have a look on typescript types.
Types
in typescript variables is going to be defined as follows
var|let|const variableName : type = value
and the code we have seen above won't compile as once you assign a type to variable you can't change this type
let x: Number = 6 // tsc: this a Number
x = "I can be string" //tsc: No you can't
Typescript offer us some basic types called everyday types such as
- string
- number
- boolean
- any: any type
- strings[]: array of strings (could be any other value)
- undefined & null
Furthermore some utility types:
- Readonly: can't be reassigned
- Record: Key value pair (like in maps)
You may also union types (ex. string|null
) this means the variable can be a number or null
wait a minute if variable is string it's also can be null why should I explicitly annotate it? It's more readable and clarify that this variable is permitted to be null.
Never type
Another that was new to me in typescript and may be new to you also is Never
type.
Never
type is more related with functions return type it's main this function will NEVER return not even void.
Look for the following examples.
const logging = (message)=> console.log(message)
logging("I ❤️ Typescript") // "I ❤️ Typescript" is logged into console
logging
function will log the passed message in to the console then return void (in other word nothing.) Now consider this function
const loggingForever = (message)=> {
while (true) {
console.log(message)
}
}
loggingForever("I ❤️ Typescript")
loggingForever
function will log the passed message the log it again the again ... until your computer crash or the sun explode whether of them happens first XD. but it will NEVER return, so the typescript version of these functions will be as follows
const logging = (message:string):void=> console.log(message)
const loggingForever = (message:string):never=> {
while (true) {
console.log(message)
}
}
// another case your function may `Never` return is when it throw an error
const throwError = (errorMessage: string): never => throw new Error(errorMessage);
Do you know another case where function will return type is never
? leave a comment.
Literal type
It's more a concrete subtype used to anither wide type (ex. 1 is colud be subtype of number
type)
There are three sets of literal types available in TypeScript today: strings, numbers, and booleans; by using literal types you can allow an exact value which a string, number, or boolean must have.
An example of literal types is a function that's simulates rolling a dice or flipping a coin
const flipCoin = () :"head"|"tail" => return (Math.floor(Math.random() * 2) + 1) == 1? "head"|"tail"
flipCoin function will return only two values "head" or "teal" any other value will cause error
of course there are more to be said about literal types to be mentioned but this article is an introduction about all types, are you still curious about? read the official docs here
Object types
Now, you may wonder how to add type annotation to objects, there's simple basic example how it's done
//js way
let fullname1 = {
firstname:"Eslam",
lastname:"Ahmed"
}
//ts way
let fullname2:{
firstname:string,
lastname:string
} = {
firstname:"Eslam",
lastname:"Ahmed"
}
//or explicitly
type fn = {
firstname:string,
lastname:string
}
let fullname3:fn = {
firstname:"Eslam",
lastname:"Ahmed"
}
/*as you expect this will cause compilation error
"Property 'lastname' is missing in type '{ firstname: string; }' but required in type 'fn'."
*/
let fullname4:fn={firstname:"Hossam"}
let's write in typescript
Enough talking about types for today. Now -I hope- you are familiar with basic types and functions in typescript. Why not apply what we learned on writing an famous algorithm called binary search. Binary search is a search algorithm with time complexity of O(log(n))
(if you are not familiar with big O notation O(log(n)) means if you are searching in 1024 value you are going to find the desired value if it exists in only log(1024) = 10 steps in worst case.)
Algorithm steps is simply that:
consider you have n sorted elements the first in position 0 and the last in position n-1 in array called values
and you are searching for the value v
- declare two variables
start = 0
,end = n-1
. the search range [0:n-1] with length n - let pos = floor((end-start)/2)
- if
values[pos]
equalsv
the return pos - if not then check if
values[pos]
less thanv
if that true change the search range tostart = pos
,end = n-1
but if values[pos]less than
vthe rage will be
start =0,
end = pos` - repeat from step 2 until start = end
const binarySearch = (nums: number[], v: number): number => {
let start: number = 0;
let end: number = nums.length - 1;
while (start <= end) {
let pos: number = Math.floor((start + end) / 2);
pos;
if (nums[pos] === v) {
return pos + 1;
}
if (v > nums[pos]) {
start = pos + 1;
} else {
end = pos - 1;
}
}
// if v doesnot exist return -1
return -1;
}
That's it for today, if you liked the content react with it, if you have a question or feedback kindly leave a comment. bye :wave: