Learning TypeScript: Part One

What follows is a stream-of-consciousness replay of me messing around with TypeScript. It’s from the point of view of a vaguely competent JavaScript hacker. I’m including the warts and brain-farts in the hopes they’re either interesting or useful.


> Google “getting started with TypeScript”, click to TypeScript in Five Minutes.

OK, cool, so types are specified for the parameters and output of a function by adding a trailing colon and type name, like this.

function isBigString(someParameter: string): boolean {
  return (someParameter.length > 4 );
}

They also have a concept of “Interfaces”, where you can specify the shape of an object, like this.

interface Person {
  firstName: string;
  lastName: string;
}

It seems kinda weird that they use css-style notation (declarations end with semicolons) rather than JavaScript object notation, but whatevs. Easy, peasy.

> Install Visual Studio Code, the suggested IDE for TypeScript, also made by Microsoft.

Hey, this is pretty snazzy. Works really well with TypeScript, which… well duh.

Wait, how do you open a project in VSC from command line?

> vsc .

No, that’s not it.

> vs .

Nope, not that either.

> Google “open visual studio code from command line”. Find this setup page.

OK, have to open the command pallete and install the shell command.

> code .

That’s the ticket.

OK, let’s go deeper than the five-minute tutorial. Looks like typescriptlang.org has a bunch of Quickstart guides. I’ll try the React guide.

They’re using create-react-app so I have to install that first.

> npm install -g create-react-app

then

> create-react-app my-app --scripts-version=react-scripts-ts

Alright, now it’s doing a bunch of stuff. Probably installing a million dependencies.

> ls node_modules

Confirmed, that’s one million modules. Somewhere a neckbeard is crying. OK, whatevs.

> npm start

And there it goes.

Compiled successfully!

You can now view my-app in the browser.

  Local:            http://localhost:3000/
  On Your Network:  http://10.5.96.6:3000/

Note that the development build is not optimized.
To create a production build, use npm run build.

Hey, that’s really cool! It automatically makes the site available on my local network.

> Go to http://10.5.96.6:3000 in my iPhone

Yup, there it is. Well hell, that makes mobile testing easy.

> npm test

What the heck?

Determining test suites to run...
--watch is not supported without git/hg, please use --watchAll
npm ERR! Test failed.  See above for more details.

> google “watch is not supported without git/hg”, read this issue on github.

Ugh, do I need to change the “watch” command to “watchAll”? Where do I even do that?

> read more

Oh! It’s just complaining because I don’t have git initialized in this project. That could be more clear.

> git init
> npm test

Back in business.

PASS  src/App.test.tsx
  ✓ renders without crashing (19ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.327s
Ran all test suites related to changed files.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

Oh, I like this. Really well done.

> Go back to the React walkthrough and create Hello.tsx using sample code.

Hmm… why does the file start with this comment?

// src/components/Hello.tsx

I don’t get it. Is that necessary? There must be some meaning here. Does that somehow help the compiled (ahem transpiled) code map to the source code? Oh wait, it’s probably just so I know where the file should go. I’m an idiot.

> Continue the tutorial, implementing the new component and adding CSS.

Hmm… plain old CSS. What am I a caveman? What transpiled-to-css languages are the cool kids using nowadays?

> Googles around to see what people are using.

Looks like Sass is still the go-to. Anyway, that was a pointless diversion. I hate myself.

> Continue the tutorial, wherein we start writing tests with Jest.

Looks like I’m supposed to install a bunch of stuff now.

> npm install -D enzyme @types/enzyme react-addons-test-utils

Uh oh, first chink in the armor, Ted.

➜  test3 git:(master) ✗ npm install -D enzyme @types/enzyme react-addons-test-utils
npm WARN deprecated nomnom@1.6.2: Package no longer supported. Contact support@npmjs.com for more info.
npm WARN ajv-keywords@3.2.0 requires a peer of ajv@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN react-addons-test-utils@15.6.2 requires a peer of react-dom@^15.4.2 but none is installed. You must install peer dependencies yourself.

+ @types/enzyme@3.1.11
+ react-addons-test-utils@15.6.2
+ enzyme@3.3.0
added 28 packages from 33 contributors and audited 30811 packages in 16.696s
found 0 vulnerabilities

What the hell is nomnom? And why would I contact support@npmjs.com about it? I’m fairly certain they would tell me to f*** right off if I said “uh… could you help me with nomnom?” The docs are inscrutable. “It noms your args and gives them back to you in a hash.” Gee thanks. Maybe it’s clear to regular people and I’m just stupid. Or maybe nom just sucks. Well it’s only deprecated, let’s skip that warning for now.

> Google “ajv-keywords@3.2.0 requires a peer of ajv@^6.0.0 but none is installed. You must install peer dependencies yourself”, find this github issue for npm.

Umm… so… that’s a lot of words. What do I need exactly? Am I supposed to install ajv@^6.0.0? The issue is opened on npm itself, not on ajv. That seems bad. What is ajv anyway? Oh, JSON schema validator? Alright then.

> read this stackoverflow article about the issue.

OK, so that says I’m supposed to update my installation of npm and install ajv@6directly.

> take a flyer, update npm and install ajv directly

> npm install -D ajv@6

Now I’ll try that other command again, see if I get the same errors.

➜ test3 git:(master) ✗ npm install -D enzyme @types/enzyme react-addons-test-utils
npm WARN deprecated nomnom@1.6.2: Package no longer supported. Contact support@npmjs.com for more info.
npm WARN react-addons-test-utils@15.6.2 requires a peer of react-dom@^15.4.2 but none is installed. You must install peer dependencies yourself.

+ @types/enzyme@3.1.11
+ enzyme@3.3.0
+ react-addons-test-utils@15.6.2
updated 3 packages and audited 30817 packages in 10.298s
found 0 vulnerabilities

Success! I got past that error about ajv.

> googles “react-addons-test-utils@15.6.2 requires a peer of react-dom@^15.4.2 but none is installed. You must install peer dependencies yourself.”

Ok, reading several different threads and github issues (the humanity!), but eventually find this one, which explains

There is no bug here. react-addons-test-utils doesn’t exist in React 16. Use react-dom/test-utilsinstead.

Bloody hell… ok, so the TypeScript/React tutorial is based on an older version of React. Let’s see if the tutorial has any issues or pull requests addressing this. Ah yes, there are several. Some with different solutions. This one looks the best. It’s approved, but for some reason it’s not merged. Why can’t they keep things up-to-date? But my github is full of stuff I’ll never touch or keep up to date myself, so who am I to judge? Well, let’s look at the code.

OK, I need to install a different set of test helpers, and I need a test-setup file. Hmm… I wonder if I even needed that ajv thing if I’m updating this other stuff. Well, lemme uninstall react-addons-test-utils and that ajv thing first.

> npm uninstall react-addons-test-utils
> npm uninstall ajv@6
&gt; npm install -D enzyme @types/enzyme <span class="x x-first x-last">enzyme-adapter-</span>react-<span class="x x-first x-last">16 @types/enzyme-adapter-react-16 react-</span>test-<span class="x x-first x-last">renderer</span>

OK, this is looking groovy. Now I’ll add the test helper file as mentioned in the pull request.

Wait… now my test-runner (which I’ve kept running this whole time) is failing.

Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
before using any of Enzyme's top level APIs, where `Adapter` is the adapter
corresponding to the library currently being tested. For example:

import Adapter from 'enzyme-adapter-react-15';

To find out more about this, see http://airbnb.io/enzyything frme/docs/installation/index.html

What? Why is it complaining about enzyme-adapter-react-15? That doesn’t make sense, I installed everything for react-16. Suck a butt.

> goes down a long rabbit hole of google searches and whatnot with no success.

Why does everything have to be so dang hard? Ugh, why can’t they keep the stupid tutorial up-to-date? This is such a pain. I HAVE EVERYTHING!

> Realize I never restarted the test-runner, so it never picked up my test setup file. Restart the test-runner.

Oh yeah, I’m an idiot. It’s happy again.

PASS  src/components/Hello.test.tsx
 PASS  src/App.test.tsx

Test Suites: 2 passed, 2 total
Tests:       6 passed, 6 total
Snapshots:   0 total
Time:        5.571s
Ran all test suites related to changed files.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

Wrapup

So… this all probably took me about 10–15 minutes to do in realtime and about 2–3 hours to document in this post (I’m a developer, so multiply everything by 3), but at this point I’m at a good stopping point. I’ve got it all running, learned a few things. Out of respect for the reader, let’s call this Part One and I’ll pick it up for Part Two in the next post.

Five Parts of an Honest Apology

sorry-2798346_1920

An honest apology is a powerful tool that will serve you well throughout your life. It can ease your conscience and it can strengthen a relationship. It’s not easy, and some people never master this skill. Having the ability to make a heartfelt apology is a mark of emotional maturity.

I believe you need five ingredients to make a full, honest, and heartfelt apology.

  1. Say you’re sorry. Look the offended party in the eye, and include their name.
  2. State what you did wrong. Be clear about what you did. This isn’t the time to argue. If you disagree about what happened, say what you did honestly and simply.
  3. Say why your actions were wrong. How was the action wrong, unfair, or unethical? You must understand why your actions were wrong to take responsibility.
  4. Acknowledge the impact of your actions. Show empathy, that you understand the impact of your actions. More than anything people want you to acknowledge how they feel. It also opens the dialog for them to clarify the impact to you.
  5. Say how you will change your behavior. An apology should be an acknowledgement that you need to change. If you won’t work to improve your behavior, you’re not really sorry.

Simple Example

I’m sorry Bill. I took the last piece of pizza. I wasn’t paying attention, so you didn’t get your share. I understand if you feel cheated. I will do my best to hold back next time and make sure you everyone gets a fair share. Do you want the rest of the garlic bread?

More Than Words

Those five ingredients are about the words of the apology. But there’s more to it. They can’t just be words. You need to honestly regret your actions. You need to want to change. You need to work to make that change.

Without that intention to change an apology is just hollow manipulation. And without that work to change apologies become meaningless over time.

It’s Difficult and That’s a Good Thing

Offering a good apology can be really difficult. It’s part of human nature that we don’t like to admit when we’re wrong. We don’t like to admit our mistakes. We don’t like to think of ourselves as the “bad guy” in our own internal morality play.

But it should be hard. It should be uncomfortable. That’s why it’s meaningful. That’s what motivates us to change. Admitting our mistakes and learning from them is how we grow. That’s how we become better people.