{Typescript}
Supercharging Your JavaScript Development
{Hello!}
Javascript is free!
function countCharacter(value){
return value.length
}
var name = "Danger"
countCharacter(name) // 5
var name = 1
countCharacter(name) // ?
var name = false
countCharacter(name) // ?
// Previously: sayMyName(firstName, lastName) { ...
function sayMyName(fullName) {
console.log(`You acting kind of shady, ain't callin' me ${fullName}`);
}
sayMyName("BeyoncΓ©", "Knowles");
# var.camp 2.0
if(typeof name !== string) throw "Name should be string";
// find the error in this code
const obj = { width: 10, height: 15 };
const area = obj.width * obj.heigth;
# VAR.CAMP 2.0
Ever written something like this?
<div>
{
data.products.map(item=><Card data={item}/>); // π΅ Cannot read the property map of undefined .. or blah blah
}
</div>
// javascript has loose documentation
// what is the type of a and b
function add(a, b) {
return a + b
}
const inputA = input()("Some async input for a!") // inputA could be anything
const inputB = input()("Some async input for b!") // inputB could be anything
add(inputA, inputB)
# VAR.CAMP 2.0
TS provides documentation
Move potential errors from runtime to compile time
function add(a: number, b: number): number {
return a + b
}
add(3, "4")
// π΅ Argument of type 'string' is not assignable to parameter of type 'number'.
Of course we can have something like JS Docs
/**
* Add two numbers
* @param {number} a
* @param {number} b
* @returns {number} total value
*/
function sum(a, b) { /* ... */ }
- Nothing stops JSDoc descriptions from being wrong about code.
- Even if your JSDoc descriptions were previously correct, during code refactors it can be difficult to find all the now-invalid JSDoc comments related to your changes.
- Describing complex objects is unwieldy and verbose.
# VAR.CAMP 2.0
# VAR.CAMP 2.0
interface Address {
street: string;
city: string;
state: string;
zipCode: string;
}
interface User {
name: string;
email: string;
password: string;
address: Address;
}
function createUser(name: string, email: string, password: string, address: Address): User {
return {
name,
email,
password,
address : address
};
}
const address = {
street: "123 Main St",
city: "Anytown",
state: "CA",
zipCode: "12345",
};
const newUser = createUser("John Doe", "john@example.com", "secret", address);
Great documentation
# VAR.CAMP 2.0
Stronger developer tooling

{Typescript}
Let's talk about Typescript !
Start with zero
# VAR.CAMP 2.0

# VAR.CAMP 2.0

# VAR.CAMP 2.0
Types are opt-in

Created By Microsoft in early 2010 and open-sourced in 2012.
Typescript has four things
- Programming language
- Type checker
- Compiler
- Language server
# VAR.CAMP 2.0
# VAR.CAMP 2.0

Notations!
# VAR.CAMP 2.0
# VAR.CAMP 2.0
function sayMyName(fullName) {
console.log(`Hello ${fullName}`);
}
sayMyName("BeyoncΓ©", "Knowles"); // π΅ Expected 1 argument, but got 2.
const firstName = "Georgia";
const nameLength = firstName.length(); // π΅ This expression is not callable.

# VAR.CAMP 2.0
Some of the basic primitives in Typescript
- number
- string
- boolean
- undefined
- null
let someNumber = 10;
let someString = "Hello String";
let isLive = true;
let someUndefined;
let somePossibleNull = Math.random() > 0.5 ? null : 10;
someNumber.toFixed(0.2)
someString.length // 11
somePossibleNull.toFixed() // π΅ possibly null
Some of the basic primitives in Typescript
- number
- string
- boolean
- undefined
- null
# VAR.CAMP 2.0
Type system
Set of rules for a language to understand what types in a program contract may have.
Simply Typescript system works by
β’ Reading in your code and understanding all the types and values in existence
β’ For each value, seeing what type its initial declaration indicates it may contain
β’ For each value, seeing all the ways itβs used later on in the code
β’ Complaining to the user if a valueβs usage doesnβt match its type
# VAR.CAMP 2.0
Type of errors
Syntax error : Blocking Typescript from being converted to Javascript
let let wat;
//
~~~
// Error: ',' expected.
Type error : Something mismatched has been detected by the type checker
let eventName : string = "Var.Camp 2.0";
eventName = "Var.Camp 2.0";
eventName = 20; // π΅ Type 'number' is not assignable to type 'string'.
eventName.toSomething(); // π΅ Type 'number' is not assignable to type 'string'.
type possiblyNumberOrString = number | string;
let value : possiblyNumberOrString = Math.random() > 0.5 ? 12 : "Twelve";
let physicist = Math.random() > 0.5 ? "Marie Curie" : 84;
physicist.toString(); // Ok vaild for both type
physicist.toUpperCase(); // π΅ Error: Property 'toUpperCase' does not exist on type 'string | number'.
physicist.toFixed(); // π΅ Property 'toUpperCase' does not exist on type 'number'.
# VAR.CAMP 2.0
Union Types
// Type of scientist: number | string
let scientist = Math.random() > 0.5 ? "Rosalind Franklin" : 51;
scientist.toUpperCase(); // π΅ Property 'toUpperCase' does not exist on type 'string | number'.
if (scientist === "Rosalind Franklin") {
scientist.toUpperCase(); // Ok
}
if (typeof scientist === "string") {
scientist.toUpperCase(); // Ok
}
typeof scientist === "string" ? scientist.toUpperCase() // Ok: string
: scientist.toFixed(); // Ok: number
# VAR.CAMP 2.0
Narrowing
const poet = {
born: 1935,
name: "Mary Oliver",
};
poet['born']; // Type: number
poet.name; // Type: string
poet.end; // π΅ Error: Property 'end' does not exist on type '{ born: number; name: string; }'.
type Poet = {
born: number;
name: string;
};
let poetLater: Poet;
// Ok
poetLater = {
born: 1935,
name: "Sara Teasdale",
};
poetLater = "Emily Dickinson"; //π΅ Error: Type 'string' is not assignable to 'Poet'.
# VAR.CAMP 2.0
Object types
type WithFirstName = {
firstName: string;
};
type WithLastName = {
lastName: string;
};
const hasBoth = {
firstName: "Lucille",
lastName: "Clifton",
};
let withFirstName: WithFirstName = hasBoth; // Ok: `hasBoth` contains a `firstName` property of type `string`
let withLastName: WithLastName = hasBoth; // Ok: `hasBoth` contains a `lastName` property of type `string`
# VAR.CAMP 2.0
Structural typing
type FirstAndLastNames = {
first: string;
last: string;
};
// Ok
const hasBoth: FirstAndLastNames = {
first: "Sarojini",
last: "Naidu",
};
const hasOnlyOne: FirstAndLastNames = {
first: "Sappho"
};
// π΅ Property 'last' is missing in type '{ first: string; }'
// π΅ but required in type 'FirstAndLastNames'.
const extraProperty: FirstAndLastNames = {
first: "Sarojini",
last: "Naidu",
age : 10
};
// π΅ 'age' does not exist in type 'FirstAndLastNames'.
# VAR.CAMP 2.0
Using Checking
type Book = {
author?: string; // optional author
pages: number;
};
// Ok
const ok: Book = {
author: "Rita Dove",
pages: 80,
};
const missing: Book = {
author: "Rita Dove",
};
// π΅ Error: Property 'pages' is missing in type
// '{ author: string; }' but required in type 'Book'.
# VAR.CAMP 2.0
Optional properties
const poem = Math.random() > 0.5
? { name: "The Double Image", pages: 7 }
: { name: "Her Kind", rhymes: true };
/**
* {
* name : string;
* pages : number;
* }
* |
* {
* name : string;
* rythmes : boolean
* }
*
*/
poem.name; // string
poem.pages; // number | undefined
poem.rhymes; // booleans | undefined
# VAR.CAMP 2.0
Inferred object union types
type Poet = {
born: number;
name: string;
};
interface Poet {
born: number;
name: string;
}
let valueLater: Poet;
// Ok
valueLater = {
born: 1935,
name: 'Sara Teasdale',
};
valueLater = "Emily Dickinson"; // π΅ Error: Type 'string' is not assignable to 'Poet'.
// π΅ Error: Type 'boolean' is not assignable to type 'number'.
valueLater = {
born: true,
name: 'Sappho'
};
# VAR.CAMP 2.0
Interfaces
interface Animal {
name: string;
sound: string;
readonly legs: number;
run(speed: number): void;
}
interface Cat extends Animal {
meow(): void;
}
// OK !
const myCat: Cat = {
name: "Fluffy",
sound: "meow",
legs: 4,
run(speed: number) {
console.log(`I'm running at ${speed} mph!`);
},
meow() {
console.log("Meow!");
},
};
# VAR.CAMP 2.0
Some differences
{ More }
// any
let anyValue: any;
anyValue = "Lucille Ball"; // Ok
anyValue = 123; // Ok
console.log(anyValue); // Ok
// unknown
function greetComedian(name: unknown) {
console.log(`Announcing ${name.toUpperCase()}!`); // π΅ Error: Object is of type 'unknown'.
}
// using narrowing
function greetComedianSafety(name: unknown) {
if (typeof name === "string") {
console.log(`Announcing ${name.toUpperCase()}!`); // Ok
} else {
console.log("Well, I'm off.");
}
}
greetComedianSafety("Var.Camp"); // "Announcing VAR.CAMP!"
greetComedianSafety({}); // "Well, I'm off."
# VAR.CAMP 2.0
Top types
function isNumberOrString(value: unknown) {
return ['number', 'string'].includes(typeof value);
}
function logValueIfExists(value: number | string | null | undefined) {
if (isNumberOrString(value)) {
// π³ ? Type of value: number | string
// π΅ 'value' is possibly 'null' or 'undefined'
console.log(value.toString());
} else {
// Type of value: null | undefined
console.log("value does not exist:", value);
}
}
# VAR.CAMP 2.0
Type predicates
function typePredicate(input: WideType): input is NarrowType;
function isNumberOrString(value: unknown) : value is number | string {
return ['number', 'string'].includes(typeof value);
}
function logValueIfExists(value: number | string | null | undefined) {
if (isNumberOrString(value)) {
// π Type of value: number | string
console.log(value.toString());
} else {
// Type of value: null | undefined
console.log("value does not exist:", value);
}
}
logValueIfExists(null)
# VAR.CAMP 2.0
Type predicates
interface Box<T> {
inside: T;
}
let stringyBox: Box<string> = {
inside: "abc",
};
let numberBox: Box<number> = {
inside: 123,
}
let incorrectBox: Box<number> = {
inside: false,
// π΅ Error: Type 'boolean' is not assignable to type 'number'.
}
function makeTuple<First, Second>(first: First, second: Second) {
return [first, second] as const;
}
makeTuple(true, "abc"); // OK Type of value: readonly [boolean, string]
makeTuple<string, number>("abc", 123); // OK ! Type: { key: string; value: number }
makeTuple<"abc", 123>("abc", 123); // Type: { key: "abc"; value: 123 }
makePair<string>("abc", 123); // π΅ Error: Expected 2 type arguments, but got 1.
# VAR.CAMP 2.0
Generics
// Type: Promise<unknown>
const resolvesUnknown = new Promise((resolve) => {
setTimeout(() => resolve("Done!"), 1000);
});
// Type: Promise<string>
const resolvesString = new Promise<string>((resolve) => {
setTimeout(() => resolve("Done!"), 1000);
});
// // Type: (text: string) => Promise<number>
async function lengthAfterSecond(text: string) {
new Promise((resolve) => setTimeout(resolve, 1000))
return text.length;
}
async function getData<T>(): Promise<T> {
const [data,setData] = useState<T>()
useEffect(()=>{
// set data
},[])
return data
}
interface Data {
name : string;
email : string;
}
const res = getData<Data>();
# VAR.CAMP 2.0
Generics & Async
# VAR.CAMP 2.0
Declaration files

// modules.d.ts
declare module "my-example-lib" {
export const value: string;
}
// index.ts
import { value } from "my-example-lib";
console.log(value); // Ok
// styles.d.ts
declare module "*.module.css" {
const styles: { [i: string]: string };
export default styles;
}
// component.ts
import styles from "./styles.module.css";
styles.anyClassName; // Type: string
# VAR.CAMP 2.0
Example
// styles.d.ts
declare module "*.module.css" {
const styles: { [i: string]: string };
export default styles;
}
// component.ts
import styles from "./styles.module.css";
styles.anyClassName; // Type: string
// globals.d.ts
declare const version: string;
// version.ts
export function logVersion() {
console.log(`Version: ${version}`); // Ok
}
{ Definately Typed }
- a giant community repo
- high-quality type definitions for popular libraries and modules
- Can install via npm and used in projects
- Make life easier for devs when dealing with libraries or modules
# VAR.CAMP 2.0
{
"dependencies": {
"react": "^18.1.0"
},
"devDependencies": {
"@types/react": "^18.0.9"
},
}
{ USING IDE Features }
# VAR.CAMP 2.0


# VAR.CAMP 2.0


# VAR.CAMP 2.0



