Fundamentals 12 min read

TypeScript Types: Basic Types, Type Guards, Generics, and Utility Types

This article provides a comprehensive overview of TypeScript's type system, covering basic types, type guards, generics, and built‑in utility types, complete with practical code examples and explanations of when and how to use each feature effectively.

TAL Education Technology
TAL Education Technology
TAL Education Technology
TypeScript Types: Basic Types, Type Guards, Generics, and Utility Types

TypeScript enhances JavaScript development by offering static type checking, a rich and evolving type system, and extensive ecosystem support such as @types, ESLint, IDE integrations, and the tsc/Babel compilers, which together improve code robustness and developer productivity.

Basic Types : boolean, number, string, array, tuple, enum, any, void, null, undefined, unknown, and never are introduced, each with concise usage examples.

let isDone: boolean = false;
let decLiteral: number = 6;
let name: string = "bob";
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
let fn = (a: string): void => {};
// tuple
let x: [string, number];
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error
// enum
enum GENDER { MALE = 1, FEMALE }
const genderList = [
  { label: '全部', value: '' },
  { label: '男', value: GENDER.MALE },
  { label: '女', value: GENDER.FEMALE }
];
console.log(GENDER[2]);
// any
let notSure: any = 4;
notSure.ifItExists();
notSure.toFixed();

Key TypeScript Keywords and Symbols : interface, type, extend, readonly, as, <>, !, &, |, :, typeof, keyof, etc., are listed to illustrate the language's expressive power.

Examples include defining interfaces and types, using readonly, type intersections, and type assertions with as and angle‑bracket syntax.

// type, interface
type INumorStr = number | string;
type IButtonType = 'default' | 'success' | 'danger' | 'warning' | 'text';
interface IPageParams {
  offset: number;
  readonly pageSize: number;
}
/** User search parameters */
interface IUserSearchParams {
  /** User ID */
  beautyId?: string;
  /** Nickname */
  nickname?: string;
  status?: number | string;
  gender?: number | string;
  registDate: [string, string];
  lastLoginDate: [string, string];
} & IPageParams;
const searchParamsTpl: Readonly<IUserSearchParams> = {
  beautyId: '',
  nickname: '',
  status: '',
  gender: '',
  registDate: ['', ''],
  lastLoginDate: ['', ''],
  offset: 0,
  pageSize: 30
};
// extends example
interface IConditionData {
  platId: string;
  appId: string;
  secretKey: string;
  payType: number;
}
export interface IWxConditionData extends IConditionData {
  wxBusinessNo: string;
}
export interface IZfbConditionData extends IConditionData {
  publicKey: string;
}
// type assertions
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let strLength2: number = (someValue as string).length;
function handler(event: Event) {
  const element = (event as any) as HTMLElement; // ok
}

Type Guards : TypeScript can narrow variable types within block scopes using type guards such as is, in, typeof, instanceof, and literal equality checks.

// is
interface IUserChartDataItem { key: 'user'; newPlayerCount: number; dauCount: number; rechargeCount?: number; dayDate: string; }
interface IFinChartDataItem { key: 'fin'; rechargeCount: number; rechargeAmount: number; dayDate: string; }
const isUserChartDataItem = (item: IUserChartDataItem | IFinChartDataItem): item is IUserChartDataItem =>
  !!((item as IUserChartDataItem).key === 'user');
// in
interface Foo { foo: string; }
interface Bar { bar: string; }
function test(obj: Foo | Bar) {
  if ('foo' in obj) {
    // obj is Foo
  } else {
    // obj is Bar
  }
}
// typeof
function test2(input: string | number) {
  if (typeof input === 'string') {
    // input is string
  } else {
    // input is number
  }
}
// instanceof
class FooClass {}
class BarClass {}
function test3(input: FooClass | BarClass) {
  if (input instanceof FooClass) {
    // input is FooClass
  } else {
    // input is BarClass
  }
}
// literal equality
type Foo = 'foo' | 'bar' | 'others';
function test4(input: Foo) {
  if (input !== 'others') {
    // input is 'foo' | 'bar'
  } else {
    // input is 'others'
  }
}

Generics : Generics allow defining interfaces, functions, or classes without specifying concrete types upfront, enabling type‑safe reuse.

// generic interface
interface IInterfaceT<T> {
  nickname: T;
  address: T;
}
const T13: IInterfaceT<string> = { nickname: 'Nate', address: 'BJ' };
// generic function
function test<T>(name: T): T { return name; }
test<number>(123); // returns number
test<number | string>(123); // returns number
// generic class
class Animal<T> {
  name: T;
  constructor(name: T) { this.name = name; }
  action(say: T): T { return say; }
}
let dog = new Animal<string>('旺财');
// dog.action(123); // error: number not assignable to string

Generic Utility Types : TypeScript provides built‑in utility types such as Partial, Required, Readonly, Record, Pick, Omit, Exclude, Extract, NonNullable, Parameters, and ReturnType to transform existing types.

Partial: makes all properties optional.

Required: makes all optional properties required.

Readonly: makes all properties read‑only.

Record: creates an object type with specified keys and value type.

Pick: selects a set of properties from a type.

Omit: removes a set of properties from a type.

Exclude: removes from a union type those members that are assignable to another type.

Extract: extracts from a union type those members that are assignable to another type.

NonNullable: removes null and undefined from a type.

Parameters: obtains a tuple type of a function’s parameters.

ReturnType: obtains the return type of a function.

// Partial implementation
interface IConditionData { platId: string; appId: string; secretKey: string; payType: number; }
type IPartial<T> = { [K in keyof T]?: T[K] };
type IConditionDataPartial = IPartial<IConditionData>;
// Exclude implementation
type IExclude<T, U> = T extends U ? never : T;
// Extract implementation
type IExtract<T, U> = T extends U ? T : never;
// Pick implementation
type IPick<T, K extends keyof T> = { [P in K]: T[P] };
type IConditionDataPick = IPick<IConditionData, 'appId' | 'platId'>;

The article concludes with a QR code and links to related technical articles, inviting readers to join the official WeChat community for further interaction.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GenericsUtility Typestypestype-guards
TAL Education Technology
Written by

TAL Education Technology

TAL Education is a technology-driven education company committed to the mission of 'making education better through love and technology'. The TAL technology team has always been dedicated to educational technology research and innovation. This is the external platform of the TAL technology team, sharing weekly curated technical articles and recruitment information.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.