Skip to content

Instantly share code, notes, and snippets.

@DeruiDENG
Last active October 12, 2019 06:56

Revisions

  1. DeruiDENG revised this gist Oct 12, 2019. 1 changed file with 404 additions and 28 deletions.
    432 changes: 404 additions & 28 deletions TypeScriptQuiz.md
    Original file line number Diff line number Diff line change
    @@ -1,27 +1,29 @@
    # TypeScript Homework
    # TypeScript Quiz and Answers

    Try to answer the following questions, which will help you have a better understanding of TypeScript
    New to TypeScript? No worries, this homework will help you better understand TypeScript.

    ## **Recommended reading**
    ## Recommendation

    First, the following link will help to answer the questions.

    * https://www.typescriptlang.org/docs/home.html TypeScript official site
    * https://basarat.gitbooks.io/typescript/ TypeScript Deep Dive


    Second, do more practice. **Try it in your favorite code editor**! I found it very useful in understanding important concept.

    ## Questions

    ### Basics

    **How is TypeScript we write understood by the browser?**
    **1. How is TypeScript we write understood by the browser?**



    **What is the difference between `interface` and `type` ? What is `extends`?**
    **2. What is the difference between `interface` and `type` ? What is `extends`? **



    **What is tsconfig.json?**
    **3. What is tsconfig.json?**

    Make sure you understand the important property in the following sample tsconfig.json

    @@ -53,15 +55,15 @@ Make sure you understand the important property in the following sample tsconfig



    **What is the type of the variable `a`, `b` and `c`**
    **4. 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']
    const c = ['a', 'b', 'c', 5]
    ```

    **Object Type-checking: Will the following code working without errors?**
    **5. Object Type-checking: Will the following code working without errors?**

    ```typescript
    interface Params {
    @@ -80,7 +82,7 @@ interface Params3 {
    path: string;
    }

    function hello(param: Param){
    function hello(param: Params){
    console.log(param.name, param.value);
    }

    @@ -103,7 +105,7 @@ hello(a);
    hello(b);
    ```

    **Function type-checking: Will the following code going to work?**
    **6. Function type-checking: Will the following code going to work?**

    ```typescript
    const a = (name: string): void => {
    @@ -139,7 +141,7 @@ sayHello(d);

    ### Combination of Types

    **AND**
    **7. AND**

    ```typescript
    interface A {
    @@ -153,7 +155,7 @@ interface B {
    // 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
    **8. OR**: How to declare a type that is either number or string

    ```typescript
    type A = ??;
    @@ -165,7 +167,7 @@ a = 5; // TS should not complain

    ### Type Inference

    **Functions inference: What will be inferred**
    **9. Functions inference: What will be inferred**

    ```typescript
    function add(a, b){
    @@ -180,7 +182,7 @@ function add2(a: number, b: number){



    **Object inference: What will be inferred**
    **10. Object inference: What will be inferred**

    ```typescript
    const a = {
    @@ -200,11 +202,11 @@ a.lastName = 'Deng';

    Generics knowledge is very important when you are dealing with 3rd party library like react, redux, lodash.

    **What is generics in TypeScript?**
    **11. What is generics in TypeScript?**



    **Use generic in the param of the function**
    **12. Use generic in the param of the function**

    ```typescript
    // FIXME: using generics on this function to solve the issue
    @@ -214,20 +216,20 @@ function getFirstElement(array:Array<any>){

    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`
    const two = getFirstElement(['5']); // two is also `any`
    two.split(''); // This is working
    ```

    **Use generic in the return value of the function**
    **13. Use generic in the return value of the function**

    ```typescript
    // FIXME: using generics on this function to solve the issue
    function getFirstAndCombine(array:Array<any>, 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
    const one = getFirstAndCombine([5], 6); // one should be number[] instead of any
    const two = getFirstAndCombine([5], '6'); // Should identify this issue
    ```


    @@ -238,7 +240,7 @@ Type inference is everywhere. Understanding it is very important



    **How are the following varables being inferred?**
    **14. How are the following varables being inferred?**

    ```typescript
    const a = 'name';
    @@ -250,9 +252,13 @@ 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?**
    **15. How to understand the inference of conditional types? Will this work? If not, how to fix?**

    Hints: Type Guard, Type Cast
    Hints:

    Type Guard https://basarat.gitbooks.io/typescript/docs/types/typeGuard.html,

    Type Cast https://basarat.gitbooks.io/typescript/docs/types/type-assertion.html

    ```typescript
    // Will this work?
    @@ -282,7 +288,7 @@ function fancy(a:number|string){

    ### Generate type from type

    **How to reuse the return value of a function?**
    **16. How to reuse the return value of a function?**

    ```typescript
    function getPeople(){
    @@ -303,7 +309,7 @@ function updatePeople(people:{name: string; age: number}){
    }
    ```

    **How to make some property of object optional instead of rewriting the whole interface?**
    **17.How to make some property of object optional instead of rewriting the whole interface?**

    ```typescript
    // How to make `age` property optional?
    @@ -315,7 +321,7 @@ interface ALargeInterface {



    **How to get a `subtype` of a type?**
    **18.How to get a `subtype` of a type?**

    ```typescript
    // How to get the type of the property `name` without pain?
    @@ -330,6 +336,376 @@ interface ALargeType {



    **Read more about Utility Types**

    ```typescript
    Partial<T>
    Readonly<T>
    Record<K,T>
    Pick<T,K>
    Omit<T,K>
    Exclude<T,U>
    Extract<T,U>
    NonNullable<T>
    ReturnType<T>
    InstanceType<T>
    Required<T>
    ThisType<T>
    ```

    ## Answers

    ### Basics

    **1. How is TypeScript we write understood by the browser?**



    **2. What is the difference between `interface` and `type` ? What is `extends`? **



    **3. 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"
    ]
    }

    ```



    **4. What is the type of the variable `a`, `b` and `c`**

    ```typescript
    const a = 'help'; // String literal 'help'
    let b: React.ReactNode = 'string'; // React.ReactNode, because you specify it
    const c = ['a', 'b', 'c', 5] // (string|number)[] is inferred by TypeScript compiler
    ```

    **5. 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: Params){
    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?
    // This will work
    hello({name: 'string', value: 5});

    // This will work because it has all the property needed (Type compatibility)
    hello({name: 'string', value: 5, path: 'workspace'});
    // This will work for same reason above
    hello(a);
    // This will NOT work because required property value is missing
    hello(b);

    // Please try it in your editor yourself
    ```

    **6. 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?
    // Please try it in your editor yourself
    sayHello(a); // Correct
    sayHello(b); // Incorrect
    sayHello(c); // Incorrect
    sayHello(d); // Correct
    ```



    ### Combination of Types

    **7. 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?
    type C = A & B
    ```
    **8. OR**: How to declare a type that is either number or string
    ```typescript
    type A = number | string;
    let a: A = '5';
    a = 5;
    ```



    ### Type Inference

    **9. 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];
    }

    // Return type of add2: number[]
    ```



    **10. Object inference: What will be inferred**

    ```typescript
    // Object literal type {name:string, age: number} is assigned to a
    const a = {
    name: 'David',
    age: 24,
    }

    // Will TS complain?
    a.name = 'Derui'; // Work
    a.age = '24'; // Does not work, '24' is not compatible with number
    a.lastName = 'Deng'; // Does not work, lastName does exist in literal type {name:string, age:number}
    ```



    ### Generics

    Generics knowledge is very important when you are dealing with 3rd party library like react, redux, lodash.

    **11. What is generics in TypeScript?**

    Read this

    http://www.typescriptlang.org/docs/handbook/generics.html

    **12. Use generic in the param of the function**

    ```typescript
    // Generics T is used
    function getFirstElement<T>(array: Array<T>): T {
    return array.length ? array[0] : null;
    }

    const one = getFirstElement([5]); // one is implicit `any`
    one.split('5'); // TS will now find this issue
    const two = getFirstElement(['5']); // two is also `any`
    two.split(''); // This is working
    ```

    **13. Use generic in the return value of the function**

    ```typescript
    function getFirstAndCombine<T>(array:T[], ele2:T){
    return array.length?[array[0], ele2]:[ele2];
    }

    const one = getFirstAndCombine([5], 6); // one should be number[] instead of any
    const two = getFirstAndCombine([5], '6'); // Should identify this issue
    ```



    ### Type Inference

    Type inference is everywhere. Understanding it is very important



    **14. How are the following varables being inferred?**

    ```typescript
    const a = 'name'; // string literal 'name'
    const b = 5; // number literal 5
    // Return string
    const fnA = (a: {name:string})=>{
    return a.name;
    }
    // number[]
    const c = [5, 6, 7];
    // (number|string)[]
    const d = [5, '6', 7];
    ```

    **15. 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?
    // The answer is YES!
    function fancy(a:number|string){
    // This is a Type Guard
    if(typeof a === 'number'){
    return a;
    } else {
    // Type of a narrowed to 'string'
    return a.length;
    }
    }

    // Will this work?
    function isNumber(a:number|string){
    return typeof a === 'number';
    }
    // This will NOT work
    function fancy(a:number|string){
    // TSC does not know this function is a type guard
    if(isNumber(a)){
    return a
    } else {
    return a.length;
    }
    }

    // Fix: add 'a is number'
    function isNumber(a: number | string): a is number {
    return typeof a === 'number';
    }

    ```



    ### Generate type from type

    **16. 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?
    // Yes, use ReturnType<>
    function updatePeople(people: ReturnType<typeof getPeople>) {
    // blablabal;
    }
    ```

    **17.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;
    }

    type B = Partial<ALargeInterface>
    ```
    **18.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;
    }

    // Simple
    type B = ALargeType['name'];
    ```



    **Read more about Utility Types**

    ```typescript
  2. DeruiDENG revised this gist Aug 23, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion TypeScriptQuiz.md
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ Try to answer the following questions, which will help you have a better underst



    ** What is the difference between `interface` and `type` ? What is `extends`? **
    **What is the difference between `interface` and `type` ? What is `extends`?**



  3. DeruiDENG revised this gist Aug 23, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion TypeScriptQuiz.md
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ Try to answer the following questions, which will help you have a better underst



    **What is the difference between `interface` and `type` ? What is `extends`? **
    ** What is the difference between `interface` and `type` ? What is `extends`? **



  4. DeruiDENG renamed this gist Aug 22, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. DeruiDENG created this gist Aug 22, 2019.
    350 changes: 350 additions & 0 deletions TypescriptQuiz.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,350 @@
    # 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<any>){
    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<any>, 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<T>
    Readonly<T>
    Record<K,T>
    Pick<T,K>
    Omit<T,K>
    Exclude<T,U>
    Extract<T,U>
    NonNullable<T>
    ReturnType<T>
    InstanceType<T>
    Required<T>
    ThisType<T>
    ```