TypeScript Flashcards

(31 cards)

1
Q

Type alias vs interface - when and how to use

A

Use type when:
- You need to define primitives, unions, tuples, or intersections
- You prefer more concise syntax
- You don’t need declaration merging

Use interface when:
- You want to describe object shapes
- You need declaration merging (extend interfaces across files)
- You’re working with classes (implements InterfaceName)

// Type alias
type Point = {
  x: number;
  y: number;
};

// Interface
interface DuckPoint {
  x: number;
  y: number;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Define variable that can be either number or string

A

let someUnion: number | string;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Define variable n that has the same type as some variable s.

A

let n: typeof s;

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

type Person = { age: number; name: string; alive: boolean };

Define new type that is:
- the same as age field in Person (number)
- union of field names of Person ( "age" | "name" | "alive"
- union of all types of Person (string | number | boolean)

A
type I1 = Person["age"]; // number
type I3Keys = keyof Person; // "age" | "name" | "alive"
type I3 = Person[keyof Person]; // string | number | boolean
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

const MyArray = ["a", "b"];

Define type that is the same as elements hold by MyArray (i.e. string)

A

type elemType = (typeof MyArray)[number];

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is duck typing in typescript, give some example.

A

“If it looks like a duck and quacks like a duck, it’s a duck.”

TypeScript uses structural typing, meaning an object is compatible with a type as long as it has the required properties, regardless of its explicit name.

interface DuckPoint {
  x: number;
  y: number;
}

function logPoint(p: DuckPoint) {
  console.log(`${p.x}, ${p.y}`);
}

const point3 = { x: 12, y: 26, z: 89 };
logPoint(point3); // Works! z ignored
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

You want to define a function that will narrow the type of the variable (variable is your custom object).

How is such function called?

How to define it

A

Type Guard

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

const underWater1: Fish[] = zoo.filter(isFish);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
  • What are discriminated unions
  • How to define and use them
  • How to perfrom exhaustive check in switch statement (to ensure all variants are covered).
A

When every type in a union contains a common property with literal types, TypeScript considers that to be a discriminated union (because we can narrow the type using this literal)

interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape) {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.sideLength ** 2;
    default:
      // This should never be reached, hence never type!
      // If we add some type to Shape union in the future, this will crash (useful)
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Type casting
* Simple
* Complex (i.e. when simple is not possible and we get a compiler error).

A
fixedString as any
fixedString as any as null;
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

value.toFixed()

Compiler reports that value is possibly undefined, how to assert that it is not

A

value!.toFixed()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Function definition:
Arguments are name (string), and number of boolean values (input).

A
function readButtonInput2(name: string, ...input: boolean[]) {
  // ...
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Function definition:

First argument c is a constructor function for Base class.

A

Constructor Signatures

function greet(c: new () => Base) {
  const instance = new ctor();
  instance.printName();
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

How function overloads work in typescript, write example.

A
// Overload signatures
function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;

// Implementation signature
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
  // Implementation signature can't be called directly.
  // The implementation signature must be compatible with the overload signatures.
  // Rule: Always prefer parameters with union types instead of overloads when possible.
  if (d !== undefined && y !== undefined) {
    return new Date(y, mOrTimestamp, d);
  } else {
    return new Date(mOrTimestamp);
  }
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Write a generic function with variadic argument type T

A
function firstElement<T>(arr: T[]): T | undefined {
  return arr[0];
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Typed variable f holding the following function:

const f = function firstElement<T>(arr: T[]): T | undefined {
  return arr[0];
}
A

const f: <T>(arg: T[]) => T | undefined

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Define a generic interface with single type.

A
interface Box<Type> {
  contents: Type;
}
17
Q

Define a function, where argument must be something with length: number property (two methods).

A

With Generic Constraints

interface Lengthwise {
  length: number;
}

function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
  console.log(arg.length); // We know it has a .length property
  return arg;
}

With Duck Typing

function loggingIdentity_2(arg: { length: number }) {
  console.log(arg.length); // Now we know it has a .length property, so no more error
  return arg;
}
18
Q

Generic function taking constructor of a class derived from Box as an argument

A
function createInstance<A extends Box>(c: new () => A): A {
  return new c();
}
19
Q

Define a generic function taking obj and key.

Ensure (with generics) the key to be a valid field of obj

A
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
  // The keyof operator takes an object type and produces a string or numeric literal union of its keys
  return obj[key];
}
20
Q

Define a conditional type Flatten<T> that returns type of element if array is given, or type itself if any other value is given.

A
type Flatten<T> = T extends any[] ? T[number] : T;
21
Q

Use cases and example of infer keyword

A
  • The infer keyword compliments conditional types and cannot be used outside an extends clause.
  • infer is used within conditional types to declare a type variable within our constraint to capture types dynamically within the extends clause of a conditional type.
type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
  ? Return
  : never;
22
Q

Mapped Types - what is it?

A

Mapped types allow you to create new types by transforming the properties of an existing type into a different format.

// To add, use + insteaed of -
type CreateMutable<Type> = {
  -readonly [Property in keyof Type]: Type[Property];
};

// Remove optional flag
type Concrete<Type> = {
  [Property in keyof Type]-?: Type[Property];
};
23
Q

Define class Engineer that adheres to Person interface.

A
class Engineer implements Person {
  name: string;
  age?: number;
  formatName: () => string;
}
24
Q

How combine two interfaces into one

A
// Extends
interface Dog extends Person, PaintOptions {
  // ...
}

// Intersection
// Similar to extends but differs in way how conflicts are handled.
type CombinetType = Person & PaintOptions;
25
Following code returns error. What error is it, and how to fix it. ``` interface SquareConfig { color?: string; width?: number; } let mySquare = createSquare({ colour: "red", width: 100 }); ```
``` ERROR: Object literal may only specify known properties, but 'colour' does not exist in type 'SquareConfig'. Did you mean to write 'color'? ``` Caused by **Excess Property Checks** **Workaround** ``` let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig); ``` **Another Workaround** ``` //Assign the object to another variable. let squareOptions = { colour: "red", width: 100 }; // Since assigning squareOptions won’t undergo excess property checks, the compiler won’t give you an error. let mySquare = createSquare(squareOptions); ```
26
How to define private variable in typescript class
``` private _age: number; // Private in TS, not in JS #salary: number; // Private everywhere ```
27
How to define getter / setter in typescript class
``` get age() { return this._age; } set age(value: number) { // In 4.3 can accept union type (but must save single one used by get) if (value > 0) { this._age = value; } } ```
28
Define typescript constructor which also defines public field `test2` and private `somePriv`
``` constructor(public test2: string, private somePriv: number) { // ... } ```
29
Utility Types: Change all fields to: - Optional - Required - Read Only - Defined (not null / undefined)
``` // Partial const o1: Partial; // Required const o2: Required; // Readonly const o3: Readonly; // NonNullable type T1 = NonNullable; ```
30
Utility Types: Select fields to form a new type
``` nterface Todo { title: string; description: string; completed: boolean; } // Pick type TodoPreview = Pick; // Omit type TodoPreview = Omit; ```
31
Utility Types: Get return type of function `() => string`
`type T0 = ReturnType<() => string>;` Or define own ReturnType: `type MyReturnType = T extends (...args: any[]) => infer R ? R : never;`