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.
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.
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"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 dollarsThe
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};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
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.any
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 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'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 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}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}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)}`);Proper use of basic types in TypeScript is like precisely managing different dinosaur species in Jurassic Park - it ensures safety and predictability.
| Type | Use in Jurassic Park | Example | |------|----------------------|---------| | string | Names, descriptions, identifiers | "Velociraptor", "P-12" | | number | Age, weight, costs | 5, 7500.5, 38.2 | | boolean | Statuses, conditions, flags | true, false | | any | Data of unknown structure (use with caution!) | Legacy systems, external data | | unknown | Safer alternative to any | Data requiring validation | | union types | Values that can be of different types | string | number | null | | literal types | Restricted 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."