Skip to content

Instantly share code, notes, and snippets.

@DeruiDENG
Last active October 12, 2019 06:56
Show Gist options
  • Save DeruiDENG/aee8dcb05a9f668f61b3e0ebf95247a5 to your computer and use it in GitHub Desktop.
Save DeruiDENG/aee8dcb05a9f668f61b3e0ebf95247a5 to your computer and use it in GitHub Desktop.

TypeScript Homework

Try to answer the following questions, which will help you have a better understanding of TypeScript

Recommended reading

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

{
  "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

const a = 'help';
let b: React.ReactNode = 'string';
const c = ['a', 'b', 'c']

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

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?

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

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

type A = ??;
let a: A = '5';
a = 5; // TS should not complain

Type Inference

Functions inference: What will be inferred

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

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

// 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

// 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?

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

// 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?

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?

// How to make `age` property optional?
interface ALargeInterface {
  name: string;
  age: number;
}

How to get a subtype of a type?

// 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

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment