Skip to content

Instantly share code, notes, and snippets.

@agentcooper
Last active March 22, 2018 07:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agentcooper/69d5fae557bfaf4e262a1a9003987b4e to your computer and use it in GitHub Desktop.
Save agentcooper/69d5fae557bfaf4e262a1a9003987b4e to your computer and use it in GitHub Desktop.
Record and function subtyping examples for TypeScript and Flow
/*
Try this file with both TypeScript [1] and Flow [2].
1. https://www.typescriptlang.org/play/index.html
2. https://flow.org/try/
TypeScript playground also provides a way to run the code -
check where the code is crashing.
*/
/*
Subtyping
=========
Notation: S <: T
How it reads: S is a subtype of T
T is a supertype for S
What it means: S can be safely used in a context
where a value of type T is expected
*/
// 1. Records
declare interface R0 { x: number }
declare interface R1 { x: number, y: number }
declare interface R2 { y: number }
const r0: R0 = { x: 0 };
const r1: R1 = { x: 1, y: 1 };
const r2: R2 = { y: 2 };
// R0 is expected
const recordExample = (p: R0) => {
console.log(p, p.x);
};
recordExample(r0); // R0 <: R0 OK
recordExample(r1); // R1 <: R0 OK
recordExample(r2); // R2 <: R0 FAIL
// 2. Functions
/*
Function subtyping rule
https://en.wikipedia.org/wiki/Subtyping#Function_types
type F1 = S1 -> S2
type F2 = T1 -> T2
F1 <: F2
<=>
S1 -> S2 <: T1 -> T2
<=>
T1 <: S1 and S2 <: T2
*/
const fr0 = (p: R0): number => p.x; // R0 -> number
const fr1 = (p: R1): number => p.x + p.y; // R1 -> number
const fr2 = (p: R2): number => p.y; // R2 -> number
function functionExample(f: (p: R0) => number) {
console.log(f.name, f({ x: 10 }));
}
functionExample(fr0); // OK
functionExample(fr1); // R1 -> number <: R0 -> number => R0 <: R1 FAIL
functionExample(fr2); // R2 -> number <: R0 -> number => R0 <: R2 FAIL
/*
Results
=======
Both Flow 0.68 and TypeScript 2.7 catch all 3 incorrect calls:
1 with record and 2 with functions.
For TypeScript you need to enable strictFunctionTypes option.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment