Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work...
-
Upload
kaliyah-shuker -
Category
Documents
-
view
216 -
download
0
Transcript of Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work...
![Page 1: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/1.jpg)
Safe TypeScriptAseem Rastogi
University of Maryland, College Park
End of Internship TalkJoint work with: Nikhil Swamy (RiSE, Internship mentor),
Cédric Fournet (MSRC), Gavin Bierman (Oracle),
Panagiotis Vekris (UCSD)
![Page 2: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/2.jpg)
TypeScriptGradually typed superset of JavaScript (www.typescriptlang.org)
• "Strong tools for large applications"• "Static checking, symbol-based navigation, statement completion,
code refactoring"
• "TypeScript offers classes, modules, and interfaces to help you build robust components"
• "Compiled into simple JavaScript"
Compared to JavaScript, this is a great leap forward!
![Page 3: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/3.jpg)
But Typing JavaScript is Hard !For all its dynamic idioms
• TypeScript (like Dart and Closure) gives up soundness, intentionally• Types are uniformly erased when compiling to JavaScript• E.g. casts are unchecked
• Unsound type erasure is beneficial• Lightweight codegen (highly readable JavaScript output)• Performance identical to plain JavaScript• Types don’t get in the way of good programmers
• But it also has its disadvantages• TypeScript components are not robust
![Page 4: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/4.jpg)
interface Iterator<A> { next(): A }
var x = { state:[..], index:0, next() { return state[index++]; } };client(x); //client:Iterator<number> => void TypeScript JavaScript
TypeScript compiler
function client(Iterator<number> it) { it["index"] = true;}
Client:
Provider:
var x = { state:[..], index:0, next() { return state[index++]; } };client(x);
function client(it) { it["index"] = true;}
Client:
Provider:
(Un-)Robustness of TypeScript Components
Type safety violation
![Page 5: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/5.jpg)
interface Iterator<A> { next(): A }
var x = { state:[..], index:0, next() { return state[index++]; } };client(x); //client:Iterator<number> => void TypeScript JavaScript
TypeScript compiler
function client(Iterator<number> it) { (<any> it).index = -1;}
Client:
Provider:
var x = { state:[..], index:0, next() { return state[index++]; } };client(x);
function client(it) { it.index = -1;}
Client:
Provider:
Abstraction violation
(Un-)Robustness of TypeScript Components
![Page 6: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/6.jpg)
Safe TypeScript
• Sound and efficient gradual typing is possible for idiomatic TypeScript
• Sound typing is beneficial• Finds type errors early
• Found and fixed 478 type errors in TypeScript compiler,• 1 functional correctness bug in NavierStokes, a heavily tested Octane benchmark
• Provably robust components
• But it also has its cost• A runtime performance penalty
• Ranging from 6% to 3x on 118,000 lines of code in 8 applications (details follow)
• Need to understand subtle corners of JS semantics and our type system
![Page 7: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/7.jpg)
function f(x:any):number { return x.f;}
function f(x):number { return x.f;}
app.ts tsc app.ts
TypeScript type inference
TypeScript parsing
JavaScript emittingfunction f(x) { return x.f;}
app.js
Syntactic errors
Static diagnostic- basic type errors
TypeScript Workflow
![Page 8: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/8.jpg)
function f(x:any):number { return x.f;}
function f(x):number { return x.f;}
app.ts tsc --safe app.ts
TypeScript type inference
TypeScript parsing
Safe TypeScript type checking
& instrumentation
function f(x:any):number { return RT.check(RT.Num, RT.read(x, "f"));}
JavaScript emitting
function f(x) { return RT.check(RT.Num, RT.read(x, "f"));}
app.js
- inconsistent subtyping- implicit downcast from any- variables not in scope- unsafe use of this- projecting methods as fields
Static diagnostics
Syntactic errors
Static diagnostic- basic type errors
Safe TypeScript WorkflowFully integrated into TypeScript v0.9.5 as an optional compiler flag
![Page 9: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/9.jpg)
Highlights of The Type System• Object-oriented, with a mixture of structural and nominal types
• Nominal types provide a sound model of JavaScript's semantics of classes• In contrast: TypeScript is purely structural
• Types are compiled to provide precise run-time type information (RTTI)• Allows the runtime system to enforce invariants with dynamic checks• In contrast: RTTI in TypeScript is only what is available in JavaScript
• Selective type-erasure for performance and robustness• The type system ensures that erasure does not compromise safety• In contrast: TypeScript uniformly erases all types
By example …
![Page 10: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/10.jpg)
Nominal Classes and Structural Interfaces
interface PointI { x:number; y:number}class PointC { constructor(public x:number, public y:number) { }}function f(p:PointC) { assert(p instanceof PointC);}
![Page 11: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/11.jpg)
Nominal Classes and Structural Interfaces
interface PointI { x:number; y:number}class PointC { constructor(public x:number, public y:number) { }}
f({x:0, y:0});
TypeScript output: leads to runtime error in f
function f(p:PointC) { assert(p instanceof PointC);}
Safe TypeScript: Static Type Error
{x:number;y:number} is not a subtype of PointC
![Page 12: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/12.jpg)
Nominal Classes and Structural Interfaces
interface PointI { x:number; y:number}class PointC { constructor(public x:number, public y:number) { }}
f(new PointC(0, 0));
function f(p:PointC) { assert(p instanceof PointC);}
Safe TypeScript: OK
![Page 13: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/13.jpg)
Nominal Classes and Structural Interfaces
f(new PointC(0, 0));
function f(p:PointI) { return p.x + p.y;}
Safe TypeScript: OK
PointC is a subtype of PointI
interface PointI { x:number; y:number}class PointC { constructor(public x:number, public y:number) { }}
![Page 14: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/14.jpg)
Highlights of The Type System• Object-oriented, with a mixture of structural and nominal types
• Nominal types provide a sound model of JavaScript's semantics of classes• In contrast: TypeScript is purely structural
• Types are compiled to provide precise run-time type information (RTTI)• Allows the runtime system to enforce invariants with dynamic checks• In contrast: RTTI in TypeScript is only what is available in JavaScript
• Selective type-erasure for performance and robustness• The type system ensures that erasure does not compromise safety• In contrast: TypeScript uniformly erases all types
![Page 15: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/15.jpg)
Tag Objects with RTTI to Lock Invariantsfunction f(p:any) { p.x = "boom";}
function g(p:PointI) { f(p); assert(typeof p.x === "number");}
TypeScript output: leads to runtime error in g
![Page 16: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/16.jpg)
Tag Objects with RTTI to Lock InvariantsshallowTag for structural objects
function f(p) { … } //coming up !
function g(p) { f(shallowTag(p, PointI)); …}
Safe TypeScript: Adds RTTI to objects to lock their type
shallowTag(x,t) = x.tag := combine(x.tag,t); x
function f(p:any) { p.x = "boom";}
function g(p:PointI) { f(p); assert(typeof p.x === "number");}
![Page 17: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/17.jpg)
Instrumentation of any Codefunction f(p) { write(p, "x", "boom");}
Safe TypeScript: Enforces type invariants in any code
write(o,f,v) = let t = o.rtti; o[f] = check(v, t[f]);
function f(p:any) { p.x = "boom";}
function g(p:PointI) { f(p); assert(typeof p.x === "number");}
function g(p) { f(shallowTag(p, PointI)); …}
// fails
![Page 18: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/18.jpg)
Tag Objects with RTTI to Lock InvariantsNo tagging for class instances
function g(p) { f(p); // no tagging …}
No tagging for class instances
Class instances have primitive RTTI (prototype chain)
function g(p:PointC) { f(p); assert(typeof p.x === "number");}
function f(p:any) { p.x = "boom";}
![Page 19: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/19.jpg)
Runtime Checked Downcastsfunction f(p:PointI) { assert(typeof p.x === "number");}
function g(p:any) { f(<PointI> p);}
g({x:"boom",y:0});
TypeScript output: leads to runtime error in f
![Page 20: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/20.jpg)
Runtime Checked DowncastsCheck fields invariants for structural types
function f(p) { … }
function g(p) { f(check(p, PointI));}…
Safe TypeScript: Checks downcasts at runtime
check(o, PointI) = if typeof o.x === “number” && typeof o.y === “number” then o.rtti := PointI; o else die
function f(p:PointI) { assert(typeof p.x === "number");}
function g(p:any) { f(<PointI> p);}
g({x:"boom",y:0});
![Page 21: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/21.jpg)
Runtime Checked DowncastsSimple instanceof check for class instances
function f(p) { … }
function g(p) { f(check(p, PointC));}…
check(o, PointC) = if o instanceof PointC then o else die
Fast instanceof check for class instances
function f(p:PointC) { … }
function g(p:any) { f(<PointC> p);}
g({x:"boom",y:0});
![Page 22: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/22.jpg)
Highlights of The Type System• Object-oriented, with a mixture of structural and nominal types
• Nominal types provide a sound model of JavaScript's semantics of classes• In contrast: TypeScript is purely structural
• Types are compiled to provide precise run-time type information (RTTI)• Allows the runtime system to enforce invariants with dynamic checks• In contrast: RTTI in TypeScript is only what is available in JavaScript
• Selective type-erasure for performance and robustness• The type system ensures that erasure does not compromise safety• In contrast: TypeScript uniformly erases all types
![Page 23: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/23.jpg)
Safe TypeScript adds RTTI Tags On-demandinterface 3dPointI extends PointI { z:number;}
function f(r:any) { ... }
function g(q:PointI) { f(q);}
function h(p:3dPointI) { g(p); }
function main(p:3dPointI) { h(p);}
shallowTag(x, t) = x.rtti := combine(x.rtti, t); x
Safe TypeScript adds minimum RTTI to ensure safety
function main(p) { h(p); } // no tagging
function h(p) { g(shallowTag(p, {z:number}); // diff tagging}
function g(q) { f(shallowTag(q, PointI));}
function f(r) { … }
![Page 24: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/24.jpg)
Programmer-controlled Type Erasure
A new operator on types: "Erased t"
A value of type Erased t is known to be a t statically, and at runtime it may not have RTTI
Erased types are erased from the JavaScript output
![Page 25: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/25.jpg)
Programmer Controlled Type Erasure
function f(r) { ... }
function g(q) { f(q);}
function h(p) { g(p);}
Cannot pass erased types to any context
static type error
No tagging despite loss in precision
compiles as is
Recall that previously it was:g(shallowTag(p, {z:number}))
Safe TypeScript: Erased types must only be used statically
interface 3dPointI extends PointI { z:number;}
function f(r:any) { ... }
function g(q:PointI) { f(q);}
function h(p:3dPointI) { g(p);}
interface PointI extends Erased { x:number; y:number}
![Page 26: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/26.jpg)
interface Iterator<A> { next(): A }
var x = { state:[..], index:0, next() { return state[index++]; } };client(x); //client:Iterator<number> => void
function client(Iterator<number> it) { it["index"] = true;}
Client:
Provider:
Revisiting Robust Components
Full formalization and proofs in technical report: http://research.microsoft.com/apps/pubs/default.aspx?id=224900
//runtime error
Robustness provided by Safe TypeScripttype soundness theorem
Several useful corollaries:
-- RTTI tags are always consistent-- RTTI tags evolve in subtyping hierarchy
![Page 27: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/27.jpg)
interface Iterator<A> { next(): A }
var x = { state:[..], index:0, next() { return state[index++]; } };client(x); //client:Iterator<number> => void
function client(Iterator<number> it) { (<any> it).index = -1;}
Client:
Provider:
Revisiting Robust ComponentsProvider’s perspective
![Page 28: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/28.jpg)
interface Iterator<A> extends Erased { next(): A }
var x = { state:[..], index:0, next() { return state[index++]; } };client(x); //client:Iterator<number> => void
function client(Iterator<number> it) { (<any> it).index = -1;}
Client:
Provider:
Revisiting Robust ComponentsProvider’s perspective
Stronger abstraction using erased types
Safe TypeScript provides an abstraction theorem for erased types
Full formalization and proofs in technical report: http://research.microsoft.com/apps/pubs/default.aspx?id=224900
//static error
![Page 29: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/29.jpg)
Much more …
• Arrays (with mutability controls)• Dictionaries• Inheritance• Overloading• Generics with bounded polymorphism• Optional fields/arguments/variadic functions• Auto-boxing• Primitive prototype hierarchy• Closed vs. open records• Nominal interfaces• Enums• … All these features allow us to handle practical TypeScript developments …
![Page 30: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/30.jpg)
Experience with SafeTypeScriptBootstrapping Safe TypeScript compiler (implemented in TypeScript v0.9.5)
• 90,000 lines of code (80,000 lines of TypeScript compiler)• Heavily class based, most of the code is carefully type annotated
• Static errors• 478 in total
• 98 uses of bi-variant array subtyping• 130 uses of covariant method argument subtyping• 128 cases of variable scoping issues• 52 cases of projecting a method (leading to potential unsound use of this
parameter)• …
• Runtime errors• 26 failed downcasts• 5 in our own code !
15% runtime overhead of type safety
![Page 31: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/31.jpg)
Experience with SafeTypeScriptCompiling TypeScript v1.1
• 18,000 lines of code• Heavily interface based
• Static errors• 81 in total
• Mainly variable scoping and array subtyping
3x runtime overhead of type safety
High overhead because of more structural types
Have not optimized Safe TypeScript runtime for structural types
![Page 32: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/32.jpg)
Experience with SafeTypeScriptOctane benchmarks
• 10,000 lines of code
• Static errors• Found 1 variable scoping bug in heavily tested NavierStokes
• High runtime overhead when no annotations• 2.4x (Splay) to 72x (Crypto), Average: 22x
• Performance recovers once we add type annotations• Average overhead: 6.5%
![Page 33: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/33.jpg)
Demo
( Examples on Online Playground: http://research.microsoft.com/en-us/um/people/nswamy/Playground/TSSafe/)
![Page 34: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/34.jpg)
Limitations and Work in Progress
• eval and friends• Adversarial typing of unsafe constructs – Swamy et. al. POPL'14
• Implementation limitations:• Does not support external modules• Current implementation is in TypeScript v0.9.5 that has
evolved to v1.1
• Ongoing discussion about integrating Safe TypeScript in TypeScript v1.1
![Page 35: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/35.jpg)
Safe TypeScript
Download:http://research.microsoft.com/en-us/downloads/b250c887-2b79-4413-9d7a-5a5a0c38cc57/
Submitted POPL'15 paper:http://www.cs.umd.edu/~aseem/safets.pdf
Technical report (with full formalization and proofs):http://research.microsoft.com/apps/pubs/default.aspx?id=224900
Online playground:http://research.microsoft.com/en-us/um/people/nswamy/Playground/TSSafe/
Sound and efficient gradual type system for TypeScript
![Page 36: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/36.jpg)
Structural types distinguish fields from methodsHandling this soundly
class Line { constructor(public p1:Point,
public p2:Point){} public moveUp() {
this.p1.y++; this.p2.y++; }}
function g(l:{moveUp:() => void}) {
var f = l.moveUp; f();
}
function h(p:Point) {g(new Line(p, p));
}
Compiles without warnings in TypeScript• Classes are convertible with their structure
window.p1 is undefined, so p1.y crashes
SafeTypeScript• Line does not contain a field called moveUp• Only a method called moveUp
Line <: {moveUp() :void; //method p1:Point; //field p2:Point} //field
![Page 37: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/37.jpg)
class Line { constructor(public p1:Point,
public p2:Point){} public moveUp() {
this.p1.y++; this.p2.y++; }}
function g(l:{moveUp(): void}) {var f = l.moveUp; f();
}
function h(p:Point) {g(new Line(p, p));
}
Compiles without warnings in TypeScript• Classes are convertible with their structure
SafeTypeScript• Cannot project a method
Line <: {moveUp() :void; //method p1:Point; //field p2:Point} //field
Structural types distinguish fields from methodsHandling this soundly
![Page 38: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/38.jpg)
class Line { constructor(public p1:Point,
public p2:Point){} public moveUp() {
this.p1.y++; this.p2.y++; }}
function g(l:{moveUp(): void}) {l.moveUp();
}
function h(p:Point) {g(new Line(p, p));g({moveUp() { this.p1.y++;
},p1:p,p2:p});
}
Compiles without warnings in TypeScript• Classes are convertible with their structure
SafeTypeScript: Ok!
Line <: {moveUp() :void; //method p1:Point; //field p2:Point} //field
SafeTypeScript: Object literal with a methodg({moveUp : () => {this.p1.y++;}, p1:p, p2:p})
SafeTypeScript: A function is not a method
Structural types distinguish fields from methodsHandling this soundly
![Page 39: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/39.jpg)
Field Addition and DeletionDynamically typed unless it becomes static
function f(p:PointI) { p["z"] = 0; delete p.z;}
function f(p: PointI) { write(p, "z", 0); delete(p, "z"); }
SafeTypeScript: Both write and delete succeed at runtime
![Page 40: Safe TypeScript Aseem Rastogi University of Maryland, College Park End of Internship Talk Joint work with: Nikhil Swamy (RiSE, Internship mentor), Cédric.](https://reader036.fdocuments.in/reader036/viewer/2022062421/56649c765503460f9492ae43/html5/thumbnails/40.jpg)
Field Addition and DeletionDynamically typed unless it becomes static
function g(p:3dPointI) { … }
function f(p:PointI) { p["z"] = 0; g(<3dPointI> p); delete p.z;}
function g(p:3dPointI) { … }
function f(p:PointI) { write(p, "z", 0); g(check(p, 3dPointI)); delete(p, "z");}
SafeTypeScript: write succeeds at runtime
SafeTypeScript: check succeeds at runtime
SafeTypeScript: delete fails at runtime – violates invariant of g