Last active
March 22, 2018 07:44
-
-
Save agentcooper/69d5fae557bfaf4e262a1a9003987b4e to your computer and use it in GitHub Desktop.
Record and function subtyping examples for TypeScript and Flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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