JavaScript and TypeScript course · Module 6: TypeScript Basics

Basic types (string, number, boolean, any, unknown)

7 min read
In this lesson12

Welcome back to our journey through TypeScript in Jurassic Park! Today Dr. Henry Wu has a special lesson for you. Just as categorizing dinosaur species is crucial for their proper breeding and care, categorizing data in TypeScript is a fundamental element of writing safe code.

Why are types important?

Without proper categorization, chaos would quickly spread through Jurassic Park - imagine feeding predators herbivore food, or placing small, gentle species in enclosures with large predators.

In programming, types play a similar role - they prevent "mixing species" of data that shouldn't be mixed. Let's look at the basic data types in TypeScript, using examples related to park management.

String - character strings

The string type in TypeScript represents text - species names, descriptions, identifiers and other textual data.

1// Declaring string type variables
2let speciesName: string = "Tyrannosaurus Rex";
3let dnaCode: string = "ACGTTGCA";
4let enclosureCode: string = "P-12";
5
6// String operations
7let fullDescription: string = `${speciesName} (DNA code: ${dnaCode}) - enclosure ${enclosureCode}`;
8console.log(fullDescription.toUpperCase()); // Displays: "TYRANNOSAURUS REX (DNA CODE: ACGTTGCA) - ENCLOSURE P-12"

Number - numbers

The number type handles both integers and floating-point numbers. It's ideal for representing dinosaur ages, their weights, the park budget and other numeric values.

1// Declaring number type variables
2let dinosaurAge: number = 5; // in years
3let dinosaurWeight: number = 7500.5; // in kilograms
4let bodyTemperature: number = 38.2; // in degrees Celsius
5
6// Mathematical operations
7let dailyFoodRation: number = dinosaurWeight * 0.05; // 5% of weight daily
8let annualMaintenanceCost: number = dailyFoodRation * 365 * 10; // food cost in dollars

Boolean - logical values

The boolean type represents true/false values, ideal for tracking statuses, conditions or flags in the park system.

1// Declaring boolean type variables
2let isPredator: boolean = true;
3let isActive: boolean = false;
4let isAdult: boolean = dinosaurAge >= 3; // calculated value
5
6// Use in conditional logic
7if (isPredator && isActive) {
8  console.log("WARNING: Active predator! Check enclosure security!");
9}
10
11// Use in a configuration object
12let securityProtocol = {
13  requiresDoubleEnclosure: isPredator,
14  requiresNightMonitoring: isActive,
15  allowedForVisitors: !isPredator || !isActive
16};

Any - any type

The any type is like an unknown dinosaur species that can behave unpredictably. It allows assigning any value to a variable and performing any operations on it - which can be dangerous!

1// Declaring any type variables
2let researchSample: any = "DNA-123";
3researchSample = 42; // We can change the type to number
4researchSample = true; // We can change the type to boolean
5researchSample = { type: "blood", age: "unknown" }; // We can change the type to object
6
7// Dangerous operations
8researchSample.nonExistentMethod(); // TypeScript won't report an error!

WARNING: Dr. Wu strongly advises against overusing the any type - it's like letting unidentified dinosaurs into the park without proper security! Use it only as a last resort when you truly don't know what type of data you'll receive.

Unknown - unknown type, but safer

The unknown type is like a new dinosaur species in quarantine - before you release it, you must carefully check its properties.

1// Declaring unknown type variables
2let newDiscovery: unknown = fetchDataFromExcavation();
3
4// We can't perform operations directly
5// newDiscovery.method(); // Error: Object is of type 'unknown'
6
7// We must first check the type
8if (typeof newDiscovery === "string") {
9  console.log(newDiscovery.toUpperCase()); // OK
10} else if (typeof newDiscovery === "number") {
11  console.log(newDiscovery.toFixed(2)); // OK
12} else if (newDiscovery instanceof DinoFragment) {
13  console.log(newDiscovery.analyzeDNA()); // OK
14}

Literal types - restricting values

Literal types allow defining a strict set of allowed values, which is useful for example when defining dinosaur species or security zones.

1// Literal types
2type PredatorSpecies = "Tyrannosaurus" | "Velociraptor" | "Spinosaurus";
3type ThreatLevel = 1 | 2 | 3 | 4 | 5;
4type EnclosureStatus = "active" | "under maintenance" | "closed";
5
6// Using literal types
7let currentPredator: PredatorSpecies = "Velociraptor";
8let threat: ThreatLevel = 4;
9let tEnclosureStatus: EnclosureStatus = "active";
10
11// Attempting to assign a disallowed value will cause an error
12// currentPredator = "Stegosaurus"; // Error: Type '"Stegosaurus"' is not assignable to type 'PredatorSpecies'

Type Inference - automatic type detection

TypeScript can automatically infer the type of a variable based on its assigned value, allowing for more concise code.

1// Automatic type detection
2let dinoName = "Blue"; // TypeScript infers type string
3let age = 3; // TypeScript infers type number
4let isActive = true; // TypeScript infers type boolean
5
6// TypeScript prevents incorrect assignment
7// dinoName = 42; // Error: Type 'number' is not assignable to type 'string'

Union Types - union types

Union types allow specifying that a variable can take values of several different types, which is useful in many park scenarios.

1// Declaring a variable that can be string or number
2let identifier: string | number;
3
4identifier = "TREX-001"; // OK
5identifier = 12345; // OK
6// identifier = true; // Error: Type 'boolean' is not assignable to type 'string | number'
7
8// Function handling different dinosaur data types
9function processData(data: string | number | boolean) {
10  if (typeof data === "string") {
11    return data.toUpperCase();
12  } else if (typeof data === "number") {
13    return data.toFixed(2);
14  } else {
15    return data ? "ACTIVE" : "INACTIVE";
16  }
17}

Null and Undefined

In TypeScript, null and undefined are special values that can be useful for representing the absence of data, for example when a dinosaur hasn't received an RFID tag yet.

1// With strictNullChecks enabled in tsconfig.json
2let rfidTag: string | null = null; // Dinosaur hasn't received a tag yet
3let lastCheckup: Date | undefined; // Checkup hasn't been performed yet
4
5// Checking before use
6function checkStatus(dino: { name: string, tag: string | null }) {
7  if (dino.tag === null) {
8    return `${dino.name} has no RFID tag - requires tagging`;
9  } else {
10    return `${dino.name} tagged with ${dino.tag}`;
11  }
12}

Practical application of basic types

Let's consider a dinosaur health monitoring system where we use different data types:

1// Interface describing the structure of dinosaur data
2interface DinosaurData {
3  id: number;
4  name: string;
5  species: string;
6  age: number;
7  weight: number;
8  isPredator: boolean;
9  healthStatus: "good" | "fair" | "needs attention" | "critical" | null;
10  rfidTag: string | null;
11  lastCheckup: Date | undefined;
12}
13
14// Function checking whether a dinosaur needs veterinary intervention
15function needsIntervention(dino: DinosaurData): boolean {
16  // A dinosaur needs intervention if:
17  // - its health status is critical
18  // - it hasn't had a checkup in the last 30 days
19  // - it has no RFID tag
20
21  const today = new Date();
22  const thirtyDaysAgo = new Date();
23  thirtyDaysAgo.setDate(today.getDate() - 30);
24
25  return (
26    dino.healthStatus === "critical" ||
27    dino.healthStatus === null ||
28    dino.rfidTag === null ||
29    (dino.lastCheckup === undefined || dino.lastCheckup < thirtyDaysAgo)
30  );
31}
32
33// Example usage
34const raptorBlue: DinosaurData = {
35  id: 101,
36  name: "Blue",
37  species: "Velociraptor",
38  age: 5,
39  weight: 350,
40  isPredator: true,
41  healthStatus: "good",
42  rfidTag: "VR-101-BLUE",
43  lastCheckup: new Date("2023-08-15")
44};
45
46const trixie: DinosaurData = {
47  id: 205,
48  name: "Trixie",
49  species: "Triceratops",
50  age: 12,
51  weight: 8500,
52  isPredator: false,
53  healthStatus: "needs attention",
54  rfidTag: "TC-205-TRIXIE",
55  lastCheckup: undefined
56};
57
58console.log(`Blue needs intervention: ${needsIntervention(raptorBlue)}`);
59console.log(`Trixie needs intervention: ${needsIntervention(trixie)}`);

Summary

Proper use of basic types in TypeScript is like precisely managing different dinosaur species in Jurassic Park - it ensures safety and predictability.

TypeUse in Jurassic ParkExample
stringNames, descriptions, identifiers"Velociraptor", "P-12"
numberAge, weight, costs5, 7500.5, 38.2
booleanStatuses, conditions, flagstrue, false
anyData of unknown structure (use with caution!)Legacy systems, external data
unknownSafer alternative to anyData requiring validation
union typesValues that can be of different typesstringnumbernull
literal typesRestricted set of values"active""inactive"

In the next lesson we'll look at more complex types such as arrays, tuples and enumerations, which will allow us to model the structure of our park data even better.

Dr. Henry Wu reminds us: "Just as in dinosaur genetics, in TypeScript precision of types is the key to success and avoiding... surprises."

Code for this lesson: index.ts
1// Basic types in Jurassic Park
2console.log("Basic TypeScript types\n");
3
4// ===========================================
5// 1. STRING - text
6// ===========================================
7console.log("=== STRING TYPE ===");
8
9let species: string = "Tyrannosaurus Rex";
10let dnaCode: string = "ACGTTGCA";
11let paddockId: string = "P-12";
12
13// Template literals
14let fullDescription: string = `${species} (DNA: ${dnaCode}) - Paddock ${paddockId}`;
15console.log(fullDescription);
16console.log(`Uppercase: ${species.toUpperCase()}`);
17
18// ===========================================
19// 2. NUMBER - numbers
20// ===========================================
21console.log("\n=== NUMBER TYPE ===");
22
23let age: number = 5; // years
24let weight: number = 7500.5; // kg
25let temperature: number = 38.2; // °C
26let hexValue: number = 0xFF; // 255
27let binaryValue: number = 0b1010; // 10
28
29console.log(`Age: ${age} years`);
30console.log(`Weight: ${weight}kg`);
31console.log(`Temperature: ${temperature}°C`);
32
33// Mathematical operations
34let dailyFeed: number = weight * 0.05;
35let yearlyFeedCost: number = dailyFeed * 365 * 10;
36console.log(`Daily feed: ${dailyFeed}kg`);
37console.log(`Yearly cost: $${yearlyFeedCost}`);
38
39// ===========================================
40// 3. BOOLEAN - logical values
41// ===========================================
42console.log("\n=== BOOLEAN TYPE ===");
43
44let isCarnivore: boolean = true;
45let isActive: boolean = false;
46let isAdult: boolean = age >= 3;
47let isHungry: boolean = true;
48let isDangerous: boolean = isCarnivore && isHungry;
49
50console.log(`Is carnivore: ${isCarnivore}`);
51console.log(`Is active: ${isActive}`);
52console.log(`Is adult: ${isAdult}`);
53console.log(`Is dangerous: ${isDangerous}`);
54
55// Conditional logic
56if (isDangerous) {
57  console.log("Security level: CRITICAL");
58} else {
59  console.log("Security level: NORMAL");
60}
61
62// ===========================================
63// 4. ANY - any type (avoid it!)
64// ===========================================
65console.log("\n=== ANY TYPE ===");
66
67let mysteryData: any = "unknown";
68mysteryData = 123; // OK
69mysteryData = true; // OK
70mysteryData = { type: "fossil" }; // OK
71
72console.log("ANY doesn't check types - use carefully!");
73console.log("Mystery data:", mysteryData);
74
75// ===========================================
76// 5. UNKNOWN - a safer any
77// ===========================================
78console.log("\n=== UNKNOWN TYPE ===");
79
80let unknownData: unknown = "mysterious DNA sequence";
81
82// We must check the type before use
83if (typeof unknownData === 'string') {
84  console.log("Unknown data length:", unknownData.length);
85} else {
86  console.log("Not a string");
87}
88
89console.log("UNKNOWN requires a type check");
90
91// ===========================================
92// 6. NULL and UNDEFINED
93// ===========================================
94console.log("\n=== NULL AND UNDEFINED ===");
95
96let emptyValue: null = null;
97let notInitialized: undefined = undefined;
98
99let optionalSpecies: string | null = null; // can be string or null
100let optionalAge: number | undefined; // can be number or undefined
101
102console.log("Empty value:", emptyValue);
103console.log("Not initialized:", notInitialized);
104console.log("Optional species:", optionalSpecies);
105console.log("Optional age:", optionalAge);
106
107// Checking for null/undefined
108function displaySpecies(s: string | null): void {
109  if (s !== null) {
110    console.log(`Species: ${s}`);
111  } else {
112    console.log("Species unknown");
113  }
114}
115
116displaySpecies(species);
117displaySpecies(null);
118
119// ===========================================
120// 7. Summary
121// ===========================================
122console.log("\n=== SUMMARY ===");
123console.log("string - text and characters");
124console.log("number - numbers (int, float, hex, binary)");
125console.log("boolean - true/false");
126console.log("any - any type (avoid it)");
127console.log("unknown - a safer any");
128console.log("null - no value");
129console.log("undefined - not initialized");
130
131console.log("\nBasic types mastered!");

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. What does the : operator after a variable name do in TypeScript?

Hands-on tasks in the game

  • Code editor

    Define variables with string, number, and boolean types describing a dinosaur.

  • Horizontal ordering

    Arrange the elements of a typed variable declaration in TypeScript:

  • Click in order

    Arrange the elements of a TypeScript function with types:

Useful articles