# TypeScript Homework Try to answer the following questions, which will help you have a better understanding of TypeScript ## **Recommended reading** * https://www.typescriptlang.org/docs/home.html TypeScript official site * https://basarat.gitbooks.io/typescript/ TypeScript Deep Dive ## Questions ### Basics **How is TypeScript we write understood by the browser?** **What is the difference between `interface` and `type` ? What is `extends`?** **What is tsconfig.json?** Make sure you understand the important property in the following sample tsconfig.json ```json { "compilerOptions": { "outDir": "./dist/", "sourceMap": true, "strictNullChecks": false, "module": "commonjs", "target": "es5", "lib": [ "es5", "es7", "dom", "es2017" ], "jsx": "react" }, "include": [ "./src/**/*" ], "exclude": [ "node_modules" ] } ``` **What is the type of the variable `a`, `b` and `c`** ```typescript const a = 'help'; let b: React.ReactNode = 'string'; const c = ['a', 'b', 'c'] ``` **Object Type-checking: Will the following code working without errors?** ```typescript interface Params { name: string; value: number; } interface Params2 { name: string; value: number; path: string; } interface Params3 { name: string; path: string; } function hello(param: Param){ console.log(param.name, param.value); } const a: Param2 = { name: 'string', value: 5, path: 'workspace' } const b: Param3 = { name: 'string', path: 'workspace' } // Will TS complain about following code? hello({name: 'string', value: 5}); hello({name: 'string', value: 5, path: 'workspace'}); hello(a); hello(b); ``` **Function type-checking: Will the following code going to work?** ```typescript const a = (name: string): void => { console.log(name); }; const b: Function = (name: string) => { console.log(name); }; const c = (name: string, middleName: string) => { console.log(name); console.log(middleName); }; const d = (name: string): string => { console.log(name); return name; }; function sayHello(sayFn: (name: string) => void) { sayFn('David'); } // Will TS complain about following code? sayHello(a); sayHello(b); sayHello(c); sayHello(d); ``` ### Combination of Types **AND** ```typescript interface A { name: string; } interface B { age: number; } // How to use A and B to create a type that has both `name` and `age` as property? ``` **OR**: How to declare a type that is either number or string ```typescript type A = ??; let a: A = '5'; a = 5; // TS should not complain ``` ### Type Inference **Functions inference: What will be inferred** ```typescript function add(a, b){ return a + b; } add(5, 6); function add2(a: number, b: number){ return [a, b]; } ``` **Object inference: What will be inferred** ```typescript const a = { name: 'David', age: 24, } // Will TS complain? a.name = 'Derui'; a.age = '24'; a.lastName = 'Deng'; ``` ### Generics Generics knowledge is very important when you are dealing with 3rd party library like react, redux, lodash. **What is generics in TypeScript?** **Use generic in the param of the function** ```typescript // FIXME: using generics on this function to solve the issue function getFirstElement(array:Array){ return array.length?array[0]:null; } const one = getFirstElement([5]); // one is implicit `any` one.split('5'); // FIXME: This is a bug, but the TS fails to find it. const two = getFirstElement(['5']); // tow is also `any` two.split(''); // This is working ``` **Use generic in the return value of the function** ```typescript // FIXME: using generics on this function to solve the issue function getFirstAndCombine(array:Array, ele2:any){ return array.length?[array[0], ele2]:[ele2]; } const one = getFirstElement([5], 6); // one should be number[] instead of any const two = getFirstElement([5], '6'); // Should identify this issue ``` ### Type Inference Type inference is everywhere. Understanding it is very important **How are the following varables being inferred?** ```typescript const a = 'name'; const b = 5; const fnA = (a: {name:string})=>{ return a.name; } const c = [5, 6, 7]; const d = [5, '6', 7]; ``` **How to understand the inference of conditional types? Will this work? If not, how to fix?** Hints: Type Guard, Type Cast ```typescript // Will this work? function fancy(a:number|string){ if(typeof a === 'number'){ return a; } else { return a.length; } } // Will this work? function isNumber(a:number|string){ return typeof a === 'number'; } function fancy(a:number|string){ if(isNumber(a)){ return a } else { return a.length; } } ``` ### Generate type from type **How to reuse the return value of a function?** ```typescript function getPeople(){ return { name: 'Dan', age: 19 } } interface People { name: string; age: number; } // Can I reuse the return value of getPeople() instead of writing stupid code? function updatePeople(people:{name: string; age: number}){ // blablabal; } ``` **How to make some property of object optional instead of rewriting the whole interface?** ```typescript // How to make `age` property optional? interface ALargeInterface { name: string; age: number; } ``` **How to get a `subtype` of a type?** ```typescript // How to get the type of the property `name` without pain? interface ALargeType { name: { firstName: string; lastName: string; }; age: number; } ``` **Read more about Utility Types** ```typescript Partial Readonly Record Pick Omit Exclude Extract NonNullable ReturnType InstanceType Required ThisType ```