Skip to content

Instantly share code, notes, and snippets.

@eamonnboyle
eamonnboyle / UserDefinedGuard.ts
Created August 27, 2021 10:08
User Defined Type Guard
function isTextArea(input: HTMLInputElement | HTMLTextAreaElement): input is HTMLTextAreaElement {
return 'rows' in input;
}
if (isTextArea(input)) {
// input has type HTMLTextAreaElement
input.rows = 25; // Valid
}
@eamonnboyle
eamonnboyle / UserDefinedGuard.ts
Created August 27, 2021 10:07
Guard Extract Fail
function isTextArea(input: HTMLInputElement | HTMLTextAreaElement): boolean {
return 'rows' in input;
}
if (isTextArea(input)) {
// input still has union type
input.rows = 25; // Compiler error
}
@eamonnboyle
eamonnboyle / UserDefinedGuard.ts
Created August 27, 2021 10:06
Guard to Extract
if ('rows' in input) {
// input has type HTMLTextAreaElement
}
@eamonnboyle
eamonnboyle / DiscriminatedUnion.ts
Created August 27, 2021 09:49
Discriminated Union Guard
// animal has type Animal or 'Dog | Cat | Fox'
const animal: Animal = readAnimal();
if (animal.kind === "Fox") {
// animal has type 'Fox'
throw new Error('What does the Fox say?');
}
// 'Fox' removed because of throw above
// animal has type 'Dog | Cat'
@eamonnboyle
eamonnboyle / DiscriminatedUnion.ts
Created August 27, 2021 09:48
Discriminated Union
interface Dog {
kind: 'Dog';
bark(): string;
}
interface Cat {
kind: 'Cat';
purr(): string;
}
@eamonnboyle
eamonnboyle / InGuard.ts
Created August 27, 2021 09:46
in Guard
function setupInput(input: HTMLInputElement | HTMLTextAreaElement) {
if ('rows' in input) {
// These properties are only valid for HTMLTextAreaElement
input.rows = 25;
input.cols = 80;
input.wrap = 'hard';
} else {
// These properties are only valid for HTMLInputElement
input.width = 400;
input.height = 50;
@eamonnboyle
eamonnboyle / InstanceofGuard.ts
Created August 27, 2021 09:45
instanceof Guard
function setupInput(input: HTMLInputElement | HTMLTextAreaElement) {
input.value = ''; // Valid since value is common to both types
if (input instanceof HTMLTextAreaElement) {
// These properties are only valid for HTMLTextAreaElement
input.rows = 25;
input.cols = 80;
input.wrap = 'hard';
} else {
// These properties are only valid for HTMLInputElement
@eamonnboyle
eamonnboyle / TypeofGuard.ts
Created August 27, 2021 09:44
typeof Guard
// Note that the type of 'primitive' in each branch is different
switch (typeof primitive) {
case "number": return primitive.toFixed(2);
case "string": return primitive.toUpperCase();
case "boolean": return !primitive;
default: throw new Error("Unexpected type")
}
@eamonnboyle
eamonnboyle / NullGuard.ts
Created August 27, 2021 09:43
Optional Chaining
element?.innerText = 'Hello';
@eamonnboyle
eamonnboyle / NullGuard.ts
Last active August 27, 2021 09:44
Null Guard
const element: HTMLElement | null = document.getElementById('target');
element.innerText = 'Hello'; // Compiler error - null in union
if (element !== null) {
element.innerText = 'Hello'; // null removed from union
}