Functions Flashcards
(16 cards)
What are function type expressions and how do you use them in TypeScript?
Function type expressions are similar to arrow functions, defining the parameter types and return type.
// Basic function type expression type GreetFunction = (name: string) => string; const greet: GreetFunction = (name) => `Hello, ${name}`; // Multiple parameters type MathOperation = (x: number, y: number) => number; const add: MathOperation = (a, b) => a + b;
What are call signatures and how do they differ from type expressions?
Call signatures allow you to add properties to functions using object type syntax.
interface DescribableFunction { description: string; (someArg: number): boolean; }; function doSomething(fn: DescribableFunction) { console.log(fn.description); console.log(fn(6)); } // Implementation const myFunc: DescribableFunction = (n: number) => n > 5; myFunc.description = "Checks if number is greater than 5";
What are construct signatures and when would you use them?
Construct signatures define types that can be instantiated with ‘new’.
type SomeConstructor = { new (s: string): object; }; class Example { constructor(s: string) { console.log(s); } } function fn(ctor: SomeConstructor) { return new ctor("hello"); } // With both call and construct signatures interface CallAndConstruct { new (s: string): Date; (n?: number): Date; }
How do you write and use generic functions?
Generic functions allow you to work with multiple types while maintaining type safety.
function identity<T>(arg: T): T { return arg; } // Using arrow functions const identity2 = <T>(arg: T): T => arg; // Generic with constraints function firstItem<T>(arr: T[]): T | undefined { return arr[0]; } // Multiple type parameters function pair<T, U>(first: T, second: U): [T, U] { return [first, second]; }
How does type inference work with generics?
TypeScript can often infer generic types from usage context.
function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] { return arr.map(func); } // Type inference in action const numbers = [1, 2, 3]; const doubled = map(numbers, n => n * 2); // TypeScript infers number[] const strings = ["hello", "world"]; const lengths = map(strings, s => s.length); // TypeScript infers number[]
How do you use constraints with generic types?
Constraints limit what types can be used with generics using ‘extends’.
interface Lengthwise { length: number; } function logLength<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; } // Valid logLength("hello"); logLength([1, 2, 3]); logLength({ length: 10, value: 3 }); // Invalid - number doesn't have length // logLength(42); // Error!
How do you work effectively with constrained types?
You can access properties guaranteed by constraints.
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) { return obj[key]; } let obj = { a: 1, b: 2, c: 3 }; // Valid getProperty(obj, "a"); // Invalid // getProperty(obj, "z"); // Error: "z" is not in keyof Type
When do you need to specify type arguments explicitly?
Sometimes TypeScript needs help inferring types.
function create<T>(value: T): T[] { return [value]; } // Explicit type argument const stringArray = create<string>("hello"); // Complex example function combine<T>(arr1: T[], arr2: T[]): T[] { return [...arr1, ...arr2]; } // Need explicit type here const mixed = combine<string | number>([1, 2], ["a", "b"]);
How do you work with optional parameters?
Optional parameters are marked with ? and must come after required parameters.
function buildName(firstName: string, lastName?: string): string { if (lastName) { return `${firstName} ${lastName}`; } return firstName; } // Default parameters function greet(name = "World"): string { return `Hello, ${name}!`; }
How do you implement function overloads?
Function overloads allow multiple call signatures for a single function.
```typescript
function makeDate(timestamp: number): Date;
function makeDate(year: number, month: number, day: number): Date;
function makeDate(yearOrTimestamp: number, month?: number, day?: number): Date {
if (month !== undefined && day !== undefined) {
return new Date(yearOrTimestamp, month - 1, day);
}
return new Date(yearOrTimestamp);
}
// Usage
const d1 = makeDate(123456789);
const d2 = makeDate(2024, 1, 1);
~~~
How do you work with the object type in TypeScript?
The object type represents any non-primitive type.
```typescript
const obj: object = { x: 10, y: 20 };
// obj.x; // Error: Property ‘x’ does not exist on type ‘object’
// Better to use specific type
const point: { x: number; y: number } = { x: 10, y: 20 };
point.x; // OK
~~~
What is the unknown type and how is it used safely?
unknown represents any value but requires checking before use.
```typescript
function processValue(val: unknown): string {
if (typeof val === “string”) {
return val.toUpperCase();
}
if (typeof val === “number”) {
return val.toFixed(2);
}
throw new Error(“Invalid type”);
}
// Usage
let value: unknown = “hello”;
// value.toUpperCase(); // Error
if (typeof value === “string”) {
value.toUpperCase(); // OK
}
~~~
What is the never type and when is it used?
never represents values that never occur.
```typescript
function error(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}
// Exhaustive checking
type Shape = Circle | Square;
function assertNever(x: never): never {
throw new Error(“Unexpected object: “ + x);
}
~~~
How do you work with rest parameters and spread arguments?
Rest parameters collect multiple arguments into an array.
```typescript
// Rest parameters
function sum(…numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
// Rest arguments
const numbers = [1, 2, 3];
console.log(sum(…numbers));
// Typing tuple rest parameters
function concat<T extends unknown[]>(…arrays: T[]): T[number][] {
return arrays.flat();
}
~~~
How do you use parameter destructuring with TypeScript?
Parameter destructuring lets you unpack objects or arrays in parameters.
```typescript
interface User {
name: string;
age: number;
}
function printUser({ name, age }: User) {
console.log(${name} is ${age} years old
);
}
// With defaults
function printUserWithDefaults({ name = “Anonymous”, age = 0 }: Partial<User> = {}) {
console.log(`${name} is ${age} years old`);
}
~~~</User>
What is the void return type and how does it work?
void indicates a function doesn’t return a value.
```typescript
function logMessage(msg: string): void {
console.log(msg);
}
// void vs undefined
function returnsVoid(): void {
return undefined; // OK
}
function returnsUndefined(): undefined {
return undefined; // OK
}
// Contextual typing with void
type VoidFunc = () => void;
const f1: VoidFunc = () => true; // OK - return value is ignored
~~~