item 40

function shallowObjectEqual<T extends object>(a: T, b: T): boolean { 
	for (const [k, aVal] of Object.entries(a)) {
			if (!(k in b) || aVal !== (b as any)[k]) { 
				return false;
			} 
	}

	return Object.keys(a).length === Object.keys(b).length; 
}

item 41

function range(start: number, limit: number) { 
		const out = [];
		for (let i = start; i < limit; i++) {
        out.push(i);
    }
		return out; // Return type inferred as number[] 
}
function makeSquares(start: number, limit: number) { 
		const out = [];
         // ~~~ Variable 'out' implicitly has type 'any[]' in some locations
      range(start, limit).forEach(i => {
        out.push(i * i);
		});
		return out;
		          // ~~~ Variable 'out' implicitly has an 'any[]' type
}

item 42

function processValue(val: unknown) { 
	if (val instanceof Date) {
		val // Type is Date 
	}
}

//or

function isBook(val: unknown): val is Book { 
	return (
		typeof(val) === 'object' && val !== null &&
		'name' in val && 'author' in val 
	);
}

function processValue(val: unknown) {
	if (isBook(val)) { 
		val; // Type is Book
	} 
}