S SmartDocs
Serie: Typescript typescript 113 righe · Aggiornato 2025-12-27

03-advanced-types.ts

Typescript/src/02-intermediate/03-advanced-types.ts

// ============================================
// 03. Advanced Types
// ============================================

// Index Signatures
interface StringDictionary {
  [key: string]: string;
}

const dict: StringDictionary = {
  hello: "world",
  foo: "bar"
};

// Number index signature
interface NumberArray {
  [index: number]: string;
}

const arr: NumberArray = ["a", "b", "c"];

// keyof Operator
interface User {
  name: string;
  age: number;
  email: string;
}

type UserKeys = keyof User;
// "name" | "age" | "email"

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user: User = { name: "Alice", age: 25, email: "alice@example.com" };
console.log(getProperty(user, "name"));  // string

// typeof Operator
const userObj = {
  name: "Alice",
  age: 25
};

type UserType = typeof userObj;
// { name: string; age: number; }

// With functions
function createUser() {
  return { name: "Alice", age: 25 };
}

type UserReturn = ReturnType<typeof createUser>;
// { name: string; age: number; }

// Template Literal Types (TypeScript 4.1+)
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<"click">;
// "onClick"

type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type ApiEndpoint = `/${string}`;
type ApiRoute = `${HttpMethod} ${ApiEndpoint}`;

type Route = "GET /users" | "POST /users" | "GET /posts";

// Lookup Types
interface UserNested {
  name: string;
  address: {
    street: string;
    city: string;
  };
}

type UserName = UserNested["name"];
// string

type Address = UserNested["address"];
// { street: string; city: string; }

type Street = UserNested["address"]["street"];
// string

// Mapped Types (Introduction)
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Optional<T> = {
  [P in keyof T]?: T[P];
};

interface User2 {
  name: string;
  age: number;
}

type ReadonlyUser = Readonly<User2>;
// { readonly name: string; readonly age: number; }

// Conditional Types (Introduction)
type IsArray<T> = T extends Array<any> ? true : false;

type Test1 = IsArray<string[]>;  // true
type Test2 = IsArray<string>;   // false

type NonNullable<T> = T extends null | undefined ? never : T;

type T0 = NonNullable<string | number | undefined>; // string | number

export { getProperty, user, ReadonlyUser };

Articoli correlati