© Instil Software 2020 TypeScript vs KotlinJS should you make the switch?
@BoyleEamonn Eamonn Boyle eamonn.boyle@gearset.com eamonn
garth @GarthGilmour Garth Gilmour garth.gilmour@instil.co
– TS brings types and compilation to JS – Improves upon the existing strengths of JS – Makes us more productive and happy – Leverages existing JS frameworks – Interop with JS is a design goal we love typescript it solves real problems for us
– Kotlin improves upon Java in many ways – Adds null safety, DSLs, coroutines etc... – Makes us more productive and happy – Leverages existing JVM frameworks – But interop with Java is a design goal we love kotlin it solves real problems for us
JVM Java Bytecode Kotlin (JVM) Kotlin (JS) Browser JavaScript Interpreter Kotlin (Native) Machine Code & Runtime OS Kotlin (Android) ART Dalvik Bytecode
experiment: is kotlinjs worth it? – We are not using KotlinJS in production – The code written has been for labs, workshops and talks – Built several apps both TypeScript and KotlinJS – Go beyond “hello world” – Incorporate common JS libraries – Compare the experience – Tooling – Language features – Community what problem does it solve?
creating a kotlinjs react project
– Template project from IntelliJ – Grade project using Kotlin DSL – Easily integrate NPM packages creating new project the wizard
multiplatform libraries COMMON KOTLIN KOTLIN ANDROID KOTLIN JS KOTLIN NATIVE KOTLIN JVM NATIVE ARTEFACT JS BUNDLE JAR
standard library documentation excellent compatibility docs
configuring the kotlin gradle dsl plugins{ kotlin("js")version"1.6.21" kotlin("plugin.serialization")version"1.6.21" } group="org.example" version="1.0-SNAPSHOT" valktorVersion="2.0.2" repositories{ mavenCentral()} dependencies{ ...}
configuring the kotlin gradle dsl kotlin{ js(LEGACY){ binaries.executable() browser{ commonWebpackConfig{ cssSupport.enabled=true } } } } There is a new IR compiler
tasks in the kotlin gradle dsl
add multiplatform and kotlinjs packages kotlinjs, multiplatform and npm dependencies { implementation("org.jetbrains.kotlin-wrappers:kotlin-react:17.0.2-pre.290-kotlin-1.6.10") implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:17.0.2-pre.290-kotlin-1.6.10") implementation("org.jetbrains.kotlin-wrappers:kotlin-react-router-dom:6.3.0-pre.340-compat") implementation("org.jetbrains.kotlin-wrappers:kotlin-react-css:17.0.2-pre.290-kotlin-1.6.10") implementation(npm("bootstrap", "4.6.0")) implementation(npm("jquery", "1.9.1- 3")) implementation(npm("popper.js", "^1.16.1")) }
what’s the code like standard main function funmain() { valcontainer= document.createElement("div") document.body!!.appendChild(container) valapp=App.create() render(app,container) }
what’s the code like easy access to browser apis funmain() { valcontainer= document.createElement("div") document.body!!.appendChild(container) valapp=App.create() render(app,container) }
what’s the code like easy access to react library valApp=FC<Props>("Application"){ BrowserRouter{ div{ p{ Link{ to="/hello”+"SimpleComponent”}} } div{ Routes{ Route{ // … } } } }
community Round 1
its popularity continues to grow rising star on language rankings … 18 Kotlin … https://redmonk.com/sogrady/2021/03/01 /language-rankings-1-21/ The RedMonk Programming Language Rankings: January 2021
its popularity continues to grow rising star on language rankings https://insights.stackoverflow.com/survey/2020 Stack Overflow Developer Survey 2020 Most Used Language 13th Kotlin 1st JavaScript 8th TypeScript
its popularity continues to grow loved by its users https://insights.stackoverflow.com/survey/2020 Stack Overflow Developer Survey 2020 Most Loved Language 2nd TypeScript 4th Kotlin 10th JavaScript 1st Rust
TS is the largest alternative to JS https://2021.stateofjs.com/en-US/
– TypeScript is more popular than KotlinJS – As a superset of JS, reusing knowledge and assets is easier – And the transition for JS developers to TS is easier – TypeScript is well established in the JavaScript world – Many libraries include TypeScript definitions – DefinitelyTyped contains many more community, maturity and support typescript > kotlin
interop with javascript Round 2
– Only a few first class wrappers provided – It is easy to add NPM packages yourself – But how easy is it to consume that code in Kotlin? importing npm js packages gradle dsl dependencies { . . . implementation(npm("react-three-fiber", "4.2.20")) implementation(npm("react-use-gesture", "7.0.15")) implementation(npm("three", "0.119.1")) }
really easy external declarations @file:JsModule("react-three-fiber") @file:JsNonModule ... external val Canvas: RClass<RProps> external fun extend(objects: Any) external fun useFrame(callback: (dynamic, Double) -> Unit) external fun useThree(): dynamic external interface PointerEvent { val uv: Vector2 } Specify the NPM package Define any items you wish to use
– Converts TypeScript d.ts files to Kotlin external declarations – Still experimental – At time of writing, on hold until IR compiler stabilises dukat automatic generation https://kotlinlang.org/docs/js-external-declarations-with-dukat.html
– Command line tool – Installable in isolation via npm – Simply point to a .d.ts file and it will do the rest dukat usage $ dukat index.d.ts index.module_my-library.kt $ npm install dukat
dukat export function getString(): string; export function setString(input: string): void; external fun getString(): String external fun setString(input: String)
– Integrated into Gradle – Generates definitions for configured packages dukat usage Dukat tasks ----------- generateExternals generateExternalsIntegrated
dukat export interface BasicInterface { readonly field1: number; method1(): boolean; } export function buildInterface(): BasicInterface; export type ReadOnlyBasicInterface = Readonly<BasicInterface>; external interface BasicInterface { var field1: Number fun method1(): Boolean } external fun buildInterface(): BasicInterface typealias ReadOnlyBasicInterface = Readonly<BasicInterface>
– It’s a good help but has issues – Limited by differences in the languages – Not a seamless workflow – This situation may improve as the tool and Kotlin evolves not a silver bullet square peg and a round hole
– KotlinJS supports a dynamic type – You can use it in place of any type – Assign it a value of any type – Access and use members with any name – Basically switches off type checking – This can be used to quickly patch over APIs dynamic get out of jail type external fun useFrame(callback: (dynamic, Double) -> Unit)
– Object literals are common in JavaScript – KotlinJS has a helper function to create objects – This is strongly typed (inferred) but requires fields to be var jso object literals in kotlinjs Block(jso { position = brick.location.toVector3() color = brick.color })
– We can embed JavaScript directly with the js function – The code can even use Kotlin variables – Must be a compile time constant – Cannot be a runtime evaluated expression js embedding javascript private fun getToken(): String? { val tokenKey = TokenKey return js(""" localStorage.getItem(tokenKey) """) }
– As a superset, TypeScript has to win this one – The type system is geared to support JavaScript – Lots of libraries already provide TypeScript definition files – However, writing external declaration in KotlinJS is easy – Dukat exists but has fundamental limitations – You may have to write custom translation code on top interop with javascript typescript > kotlinjs
jsx vs dsl Round 3
JSX IN TYPESCRIPT JSX embeds markup inside JS / TS code export const TaskItem: FC<Props> = (props) => <tr key={props.taskIndex}> <td>{props.task.text}</td> <td> <span onClick={props.onToggle}> {pickIcon(props.task.done)} </span> </td> </tr>
val TaskItem= functionalComponent<TaskItemProps>("TaskItem"){ props -> tr{ td { +props.task.text } td { span { +pickIcon(props.task.done) } attrs { onClickFunction= { props.onToggle() } } } } } fun RBuilder.TaskItem(task: Task) = child(TaskItem) { attrs { this.task = task } } REACT DSL IN KOTLIN In Kotlin a DSL provides equivalent functionality
kotlin DSL’s are very cool a major advantage
val TaskItem= functionalComponent<TaskItemProps>("TaskItem"){ props -> tr{ td { +props.task.text } td { span { +pickIcon(props.task.done) } attrs { onClickFunction= { props.onToggle() } } } } } fun RBuilder.TaskItem(task: Task) = child(TaskItem) { attrs { this.task = task } } REACT DSL IN KOTLIN JSX is clearly a lot simpler / shorter
Then they rewrote it (without telling anyone)
val TaskItem=FC<TaskItemProps>("TaskItem"){props-> tr{ td{ +props.task.text} td{ onClick={ props.onToggle()} span{ +pickIcon(props.task.done) } } } } REACT DSL IN KOTLIN
val TaskItem=FC<TaskItemProps>("TaskItem"){props-> tr{ td{ +props.task.text} td{ onClick={ props.onToggle()} span{ +pickIcon(props.task.done) } } } } REACT DSL IN KOTLIN Builder functions not required Many attributes are cleaner attrs section is gone
The typing is ... imperfect
interface InputHTMLAttributes<T> extends HTMLAttributes<T> { max?: number | string; min?: number | string; value?: string | ReadonlyArray<string> | number; ... } Type union type PropsWithChildren<P> = P & { children?: ReactNode }; Type intersection
// Type exports erased! external fun interfaceUnionInput(input: First) external fun interfaceUnionInput(input: Second) external fun interfaceUnionOutput(): dynamic /* First | Second */ export type InterfaceUnion = First | Second; export function interfaceUnionInput(input: InterfaceUnion): void; export function interfaceUnionOutput(): InterfaceUnion; Kotlin supports proper overloads Not supported on the return type
external fun interfaceIntersectionInput(input: First /* First & Second */) external fun interfaceIntersectionOutput(): First /* First & Second */ export type InterfaceIntersection = First & Second; export function interfaceIntersectionInput(input: InterfaceIntersection): void; export function interfaceIntersectionOutput(): InterfaceIntersection; Intersection dropped
mapped and conditional types even more power in typescript type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type PromiseType<T extends Promise<any>> = T extends Promise<infer U> ? U : never; Type conditional
The languages are simply not fully compatible
manual workarounds useEffect function useEffect( effect: EffectCallback, deps?: DependencyList ): void; type EffectCallback = () => (void | Destructor); type Destructor = () => void;
useEffect union return workaround fun useEffect( dependencies: RDependenciesList? = null, effect: () -> Unit ) { // ... } fun useEffectWithCleanup( dependencies: RDependenciesList? = null, effect: () -> Rcleanup ) { // ... }
useEffect or other patterns useEffect { } useEffect(dep1, dep2) { } useEffectOnce { } useEffectOnce { cleanup { // Clean up logic goes here } }
– Kotlin’s DSL support is a powerful general purpose tool – But JSX is a single purpose solution that suits React better – TypeScript’s advanced type system is very powerful – Union, intersection and mapped types bring sanity to JS – Kotlin types (unsurprisingly) sit awkwardly on top of JS jsx vs dsl typescript > kotlin
async await vs coroutines Round 4
asynchronous programming – Async await is a good async solution in JS & TS – Engineered so it interops with Promises – Succinct promises and async/await async function loadMap(url: string): Promise<void> { const response = await fetch(url); const map = await response.text(); // ... }
coroutines – Kotlin’s more general coroutines are better – Works with other patterns than simply async – In KotlinJS, it works easily with Promises kotlin > typescript suspend fun loadMap(url: String) { val response = window.fetch(url).await() val map = response.text().await() // ... }
coroutines – Coroutines are more general and powerful – They can be used with other patterns too – With suspend functions we don’t need to “await” kotlin > typescript suspend fun loadMap(url: String) { val map = client.get<String>(url) // ... } Ktor Client
coroutines – Coroutines can be applied to other patterns too kotlin > typescript fun infinite() = sequence { var count = 0 while (true) { yield(count++) } }
elegant syntax Round 5
– Kotlin doesn’t have the ternary, but has more – when for basic pattern matching – if and when are expressions – Unit instead of void – Expression bodied functions – This creates more symmetry in code expressions kotlin > typescript
typescript chained ternaries const App: FC = () => { // ... return ( <div> // ... {gameState === GameState.Start ? <StartScreen/> : gameState === GameState.Playing ? <PlayingGame/> : gameState === GameState.Dead ? <DeathScreen/> : gameState === GameState.Win ? <WinScreen/> : null} </div> ); };
kotlin when expression val App = FC { // ... div { // ... when (gameState) { GameState.Start -> StartScreen() GameState.Playing -> PlayingScreen() GameState.Win -> WinScreen() GameState.Dead -> EndScreen() } } }
– Both languages support object destructuring – Within blocks and in lambda parameters – However, Kotlin’s is limited – Supported via componentN methods – Fixed order to properties extracted – Data classes do this automatically destructuring typescript > kotlin
const {value, color} = brick; const {value, location} = brick; Arbitrary properties extracted export const Brick: FC<Props> = ({index}) => { } Destructuring on parameters const [first, ...remaining] = bricks; Array destructuring
conclusion
they’re both very good but in different ways
Community Coroutines JSX vs React DSL Multiplatform Advanced Type System Extensions Interop with JS Expressions Destructuring Standard Library Tooling Functions
favour stable engineering
Questions?
TypeScript Vs. KotlinJS

TypeScript Vs. KotlinJS

  • 2.
    © Instil Software2020 TypeScript vs KotlinJS should you make the switch?
  • 3.
  • 4.
  • 5.
    – TS bringstypes and compilation to JS – Improves upon the existing strengths of JS – Makes us more productive and happy – Leverages existing JS frameworks – Interop with JS is a design goal we love typescript it solves real problems for us
  • 6.
    – Kotlin improvesupon Java in many ways – Adds null safety, DSLs, coroutines etc... – Makes us more productive and happy – Leverages existing JVM frameworks – But interop with Java is a design goal we love kotlin it solves real problems for us
  • 8.
  • 9.
    experiment: is kotlinjsworth it? – We are not using KotlinJS in production – The code written has been for labs, workshops and talks – Built several apps both TypeScript and KotlinJS – Go beyond “hello world” – Incorporate common JS libraries – Compare the experience – Tooling – Language features – Community what problem does it solve?
  • 10.
  • 11.
    – Template projectfrom IntelliJ – Grade project using Kotlin DSL – Easily integrate NPM packages creating new project the wizard
  • 14.
    multiplatform libraries COMMON KOTLIN KOTLIN ANDROID KOTLINJS KOTLIN NATIVE KOTLIN JVM NATIVE ARTEFACT JS BUNDLE JAR
  • 15.
  • 16.
    configuring the kotlingradle dsl plugins{ kotlin("js")version"1.6.21" kotlin("plugin.serialization")version"1.6.21" } group="org.example" version="1.0-SNAPSHOT" valktorVersion="2.0.2" repositories{ mavenCentral()} dependencies{ ...}
  • 17.
    configuring the kotlingradle dsl kotlin{ js(LEGACY){ binaries.executable() browser{ commonWebpackConfig{ cssSupport.enabled=true } } } } There is a new IR compiler
  • 18.
    tasks in thekotlin gradle dsl
  • 19.
    add multiplatform andkotlinjs packages kotlinjs, multiplatform and npm dependencies { implementation("org.jetbrains.kotlin-wrappers:kotlin-react:17.0.2-pre.290-kotlin-1.6.10") implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:17.0.2-pre.290-kotlin-1.6.10") implementation("org.jetbrains.kotlin-wrappers:kotlin-react-router-dom:6.3.0-pre.340-compat") implementation("org.jetbrains.kotlin-wrappers:kotlin-react-css:17.0.2-pre.290-kotlin-1.6.10") implementation(npm("bootstrap", "4.6.0")) implementation(npm("jquery", "1.9.1- 3")) implementation(npm("popper.js", "^1.16.1")) }
  • 20.
    what’s the codelike standard main function funmain() { valcontainer= document.createElement("div") document.body!!.appendChild(container) valapp=App.create() render(app,container) }
  • 21.
    what’s the codelike easy access to browser apis funmain() { valcontainer= document.createElement("div") document.body!!.appendChild(container) valapp=App.create() render(app,container) }
  • 22.
    what’s the codelike easy access to react library valApp=FC<Props>("Application"){ BrowserRouter{ div{ p{ Link{ to="/hello”+"SimpleComponent”}} } div{ Routes{ Route{ // … } } } }
  • 23.
  • 24.
    its popularity continuesto grow rising star on language rankings … 18 Kotlin … https://redmonk.com/sogrady/2021/03/01 /language-rankings-1-21/ The RedMonk Programming Language Rankings: January 2021
  • 25.
    its popularity continuesto grow rising star on language rankings https://insights.stackoverflow.com/survey/2020 Stack Overflow Developer Survey 2020 Most Used Language 13th Kotlin 1st JavaScript 8th TypeScript
  • 26.
    its popularity continuesto grow loved by its users https://insights.stackoverflow.com/survey/2020 Stack Overflow Developer Survey 2020 Most Loved Language 2nd TypeScript 4th Kotlin 10th JavaScript 1st Rust
  • 27.
    TS is thelargest alternative to JS https://2021.stateofjs.com/en-US/
  • 28.
    – TypeScript ismore popular than KotlinJS – As a superset of JS, reusing knowledge and assets is easier – And the transition for JS developers to TS is easier – TypeScript is well established in the JavaScript world – Many libraries include TypeScript definitions – DefinitelyTyped contains many more community, maturity and support typescript > kotlin
  • 29.
  • 30.
    – Only afew first class wrappers provided – It is easy to add NPM packages yourself – But how easy is it to consume that code in Kotlin? importing npm js packages gradle dsl dependencies { . . . implementation(npm("react-three-fiber", "4.2.20")) implementation(npm("react-use-gesture", "7.0.15")) implementation(npm("three", "0.119.1")) }
  • 31.
    really easy external declarations @file:JsModule("react-three-fiber") @file:JsNonModule ... externalval Canvas: RClass<RProps> external fun extend(objects: Any) external fun useFrame(callback: (dynamic, Double) -> Unit) external fun useThree(): dynamic external interface PointerEvent { val uv: Vector2 } Specify the NPM package Define any items you wish to use
  • 32.
    – Converts TypeScriptd.ts files to Kotlin external declarations – Still experimental – At time of writing, on hold until IR compiler stabilises dukat automatic generation https://kotlinlang.org/docs/js-external-declarations-with-dukat.html
  • 33.
    – Command linetool – Installable in isolation via npm – Simply point to a .d.ts file and it will do the rest dukat usage $ dukat index.d.ts index.module_my-library.kt $ npm install dukat
  • 34.
    dukat export function getString():string; export function setString(input: string): void; external fun getString(): String external fun setString(input: String)
  • 35.
    – Integrated intoGradle – Generates definitions for configured packages dukat usage Dukat tasks ----------- generateExternals generateExternalsIntegrated
  • 36.
    dukat export interface BasicInterface{ readonly field1: number; method1(): boolean; } export function buildInterface(): BasicInterface; export type ReadOnlyBasicInterface = Readonly<BasicInterface>; external interface BasicInterface { var field1: Number fun method1(): Boolean } external fun buildInterface(): BasicInterface typealias ReadOnlyBasicInterface = Readonly<BasicInterface>
  • 37.
    – It’s agood help but has issues – Limited by differences in the languages – Not a seamless workflow – This situation may improve as the tool and Kotlin evolves not a silver bullet square peg and a round hole
  • 38.
    – KotlinJS supportsa dynamic type – You can use it in place of any type – Assign it a value of any type – Access and use members with any name – Basically switches off type checking – This can be used to quickly patch over APIs dynamic get out of jail type external fun useFrame(callback: (dynamic, Double) -> Unit)
  • 39.
    – Object literalsare common in JavaScript – KotlinJS has a helper function to create objects – This is strongly typed (inferred) but requires fields to be var jso object literals in kotlinjs Block(jso { position = brick.location.toVector3() color = brick.color })
  • 40.
    – We canembed JavaScript directly with the js function – The code can even use Kotlin variables – Must be a compile time constant – Cannot be a runtime evaluated expression js embedding javascript private fun getToken(): String? { val tokenKey = TokenKey return js(""" localStorage.getItem(tokenKey) """) }
  • 41.
    – As asuperset, TypeScript has to win this one – The type system is geared to support JavaScript – Lots of libraries already provide TypeScript definition files – However, writing external declaration in KotlinJS is easy – Dukat exists but has fundamental limitations – You may have to write custom translation code on top interop with javascript typescript > kotlinjs
  • 42.
  • 43.
    JSX IN TYPESCRIPT JSX embeds markup insideJS / TS code export const TaskItem: FC<Props> = (props) => <tr key={props.taskIndex}> <td>{props.task.text}</td> <td> <span onClick={props.onToggle}> {pickIcon(props.task.done)} </span> </td> </tr>
  • 44.
    val TaskItem= functionalComponent<TaskItemProps>("TaskItem"){props -> tr{ td { +props.task.text } td { span { +pickIcon(props.task.done) } attrs { onClickFunction= { props.onToggle() } } } } } fun RBuilder.TaskItem(task: Task) = child(TaskItem) { attrs { this.task = task } } REACT DSL IN KOTLIN In Kotlin a DSL provides equivalent functionality
  • 45.
    kotlin DSL’s arevery cool a major advantage
  • 46.
    val TaskItem= functionalComponent<TaskItemProps>("TaskItem"){props -> tr{ td { +props.task.text } td { span { +pickIcon(props.task.done) } attrs { onClickFunction= { props.onToggle() } } } } } fun RBuilder.TaskItem(task: Task) = child(TaskItem) { attrs { this.task = task } } REACT DSL IN KOTLIN JSX is clearly a lot simpler / shorter
  • 47.
    Then they rewroteit (without telling anyone)
  • 49.
    val TaskItem=FC<TaskItemProps>("TaskItem"){props-> tr{ td{ +props.task.text} td{ onClick={props.onToggle()} span{ +pickIcon(props.task.done) } } } } REACT DSL IN KOTLIN
  • 50.
    val TaskItem=FC<TaskItemProps>("TaskItem"){props-> tr{ td{ +props.task.text} td{ onClick={props.onToggle()} span{ +pickIcon(props.task.done) } } } } REACT DSL IN KOTLIN Builder functions not required Many attributes are cleaner attrs section is gone
  • 51.
    The typing is... imperfect
  • 52.
    interface InputHTMLAttributes<T> extendsHTMLAttributes<T> { max?: number | string; min?: number | string; value?: string | ReadonlyArray<string> | number; ... } Type union type PropsWithChildren<P> = P & { children?: ReactNode }; Type intersection
  • 53.
    // Type exportserased! external fun interfaceUnionInput(input: First) external fun interfaceUnionInput(input: Second) external fun interfaceUnionOutput(): dynamic /* First | Second */ export type InterfaceUnion = First | Second; export function interfaceUnionInput(input: InterfaceUnion): void; export function interfaceUnionOutput(): InterfaceUnion; Kotlin supports proper overloads Not supported on the return type
  • 54.
    external fun interfaceIntersectionInput(input:First /* First & Second */) external fun interfaceIntersectionOutput(): First /* First & Second */ export type InterfaceIntersection = First & Second; export function interfaceIntersectionInput(input: InterfaceIntersection): void; export function interfaceIntersectionOutput(): InterfaceIntersection; Intersection dropped
  • 55.
    mapped and conditionaltypes even more power in typescript type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type PromiseType<T extends Promise<any>> = T extends Promise<infer U> ? U : never; Type conditional
  • 56.
    The languages aresimply not fully compatible
  • 57.
    manual workarounds useEffect function useEffect( effect:EffectCallback, deps?: DependencyList ): void; type EffectCallback = () => (void | Destructor); type Destructor = () => void;
  • 58.
    useEffect union return workaround funuseEffect( dependencies: RDependenciesList? = null, effect: () -> Unit ) { // ... } fun useEffectWithCleanup( dependencies: RDependenciesList? = null, effect: () -> Rcleanup ) { // ... }
  • 59.
    useEffect or other patterns useEffect{ } useEffect(dep1, dep2) { } useEffectOnce { } useEffectOnce { cleanup { // Clean up logic goes here } }
  • 60.
    – Kotlin’s DSLsupport is a powerful general purpose tool – But JSX is a single purpose solution that suits React better – TypeScript’s advanced type system is very powerful – Union, intersection and mapped types bring sanity to JS – Kotlin types (unsurprisingly) sit awkwardly on top of JS jsx vs dsl typescript > kotlin
  • 61.
    async await vscoroutines Round 4
  • 62.
    asynchronous programming – Asyncawait is a good async solution in JS & TS – Engineered so it interops with Promises – Succinct promises and async/await async function loadMap(url: string): Promise<void> { const response = await fetch(url); const map = await response.text(); // ... }
  • 63.
    coroutines – Kotlin’s moregeneral coroutines are better – Works with other patterns than simply async – In KotlinJS, it works easily with Promises kotlin > typescript suspend fun loadMap(url: String) { val response = window.fetch(url).await() val map = response.text().await() // ... }
  • 64.
    coroutines – Coroutines aremore general and powerful – They can be used with other patterns too – With suspend functions we don’t need to “await” kotlin > typescript suspend fun loadMap(url: String) { val map = client.get<String>(url) // ... } Ktor Client
  • 65.
    coroutines – Coroutines canbe applied to other patterns too kotlin > typescript fun infinite() = sequence { var count = 0 while (true) { yield(count++) } }
  • 66.
  • 67.
    – Kotlin doesn’thave the ternary, but has more – when for basic pattern matching – if and when are expressions – Unit instead of void – Expression bodied functions – This creates more symmetry in code expressions kotlin > typescript
  • 68.
    typescript chained ternaries const App:FC = () => { // ... return ( <div> // ... {gameState === GameState.Start ? <StartScreen/> : gameState === GameState.Playing ? <PlayingGame/> : gameState === GameState.Dead ? <DeathScreen/> : gameState === GameState.Win ? <WinScreen/> : null} </div> ); };
  • 69.
    kotlin when expression val App= FC { // ... div { // ... when (gameState) { GameState.Start -> StartScreen() GameState.Playing -> PlayingScreen() GameState.Win -> WinScreen() GameState.Dead -> EndScreen() } } }
  • 70.
    – Both languagessupport object destructuring – Within blocks and in lambda parameters – However, Kotlin’s is limited – Supported via componentN methods – Fixed order to properties extracted – Data classes do this automatically destructuring typescript > kotlin
  • 71.
    const {value, color}= brick; const {value, location} = brick; Arbitrary properties extracted export const Brick: FC<Props> = ({index}) => { } Destructuring on parameters const [first, ...remaining] = bricks; Array destructuring
  • 72.
  • 73.
    they’re both verygood but in different ways
  • 74.
    Community Coroutines JSX vs ReactDSL Multiplatform Advanced Type System Extensions Interop with JS Expressions Destructuring Standard Library Tooling Functions
  • 75.
  • 76.

Editor's Notes

  • #6 Lots to love in JavaScript – ubiquitous, popularity/community, succinct syntax, object literals, destructuring But it’s dynamic typing. I’m a fan of static typing
  • #7 Lots to love in JavaScript – ubiquitous, popularity/community, succinct syntax, object literals, destructuring But it’s dynamic typing. I’m a fan of static typing
  • #21 Emphasize how good it is you can start writing code
  • #22 Emphasize how good it is you can start writing code
  • #23 Emphasize how good it is you can start writing code
  • #26 Ask the question – top spot?
  • #27 Ask the question – top spot?
  • #38 TypeScript is more capable when it comes to type programming Not easy to integrate customisations (which are common) If kotlin evolves to support more TS features, less customisation will be necessary
  • #42 More libraries may come out
  • #45 We can trim it down but grouping closing braces We could also group params but So first off, THIS IS PRETTY COOL that we can do this
  • #47 We can trim it down but grouping closing braces We could also group params but So first off, THIS IS PRETTY COOL that we can do this
  • #50 Cumberbatch for cumbersome
  • #51 Cumberbatch for cumbersome
  • #54 Union done as overloads – good! Output simply dynamic - bad
  • #58 It’s not to say you can achieve the desired behaviour