Google Glass

Google Glass may finally end its embarrassing consumer life and get a job in enterprise

Google Glass is the embodiment of a product ahead of its time. Few in the tech world doubt that augmented reality wearables will eventually be big, but if the world isn’t ready for them in 2019, it most definitely wasn’t back in 2014. Google Glass was an awesome concept, but the hardware was simply too sluggish, cumbersome, and creepy to ever catch on.

Windows Phone

Microsoft never gave the Windows Phone the show it deserved

Breaking into the smartphone market is notoriously difficult, even more so when you’re trying to create a new platform altogether. Microsoft had a head start over both Apple and Google, what with the prevalence of Windows Mobile in the PDA era, but it just couldn’t catch up to Apple and Google’s Rampant success.

Though many thought Microsoft might eventually try making another Windows Phone, the fact the company adopted Android for its upcoming Surface Duo phone makes it clear the company has given up on bringing Windows to your pocket.

Fire Phone

Amazon Fire Phone review: a flawed portable store trying desperately to get your attention

Amazon had the potential to be one of the biggest players in the smartphone market, but the company bungled its first attempt so badly, it stopped trying.

The phone‘s pseudo-3D parallax screen was a gimmick, forking off Android was a bad choice for app support, battery life sucked, and it had no compelling features beyond helping you buy stuff from Amazon. And make no mistake: the phone‘s main purpose was to get you to buy stuff from Amazon.

HTC First AKA the Facebook Phone

Screen Shot 2013-04-04 at 18.37.55

Remember that time Facebook kinda sorta tried to break into the smartphone market with its ‘Facebook Home’ interface? Yeah, me neither until I came across it again for this article.

Coolest Cooler

After raising $13 million, Coolest Cooler tells backers it needs another $15 million to complete orders ...

The Coolest Cooler is the epitome of crowdfunding gone wrong. It once held the record for most crowdfunded Kickstarter project ever, at over $13 million. And yet five years after launch, there are still backers waiting to get their unit – units which turned out to be pretty mediocre.

Worse, the company announced this month it had run out of money and would not be able to deliver the remaining units or refunds – which apparently includes a third of the original backers.



No social network has come as close as Google once did to legitimately challenge Facebook. Google launched to massive momentum thanks to a clever system that gave you more control over who to share information with and excellent photos support, not to mention Google’s clout.

But it was also a bit too complicated to use and like so many Google projects, the company bungled its long term execution. It was unceremoniously killed in 2018 after a massive security oversight led to an estimated 500,000 accounts being compromised.


Once upon a time, MoviePass offered film aficionados the ability to pay $10 a month and see almost any film as often as they’d like. It seemed like it would revitalize filmgoing for a new generation. As it turns out, you can’t make a profit by allowing people to see unlimited movies for little over the price of an average single movie ticket every month.

MoviePass promptly ran out of money, angered its few remaining subscribers by constantly changing its benefits and pricing, and at one point already shut down because it couldn’t pay its creditors.

Wii U

Wii U owners begged for Spotify so Nintendo gave them Rhapsody

While part of me is remiss to call the Wii U a ‘flop’ given a few excellent titles like Super Mario 3D World, Super Smash Bros 4, and both Skyward Sword and Breath of the Wild, the console just never caught on the way the Xbox One and PS4 did. The relatively poor graphics and odd controller didn’t do much for people, and the console sold poorly.

For a while, it looked like Nintendo might be facing serious trouble; it didn’t have the corporate backing Microsoft and Sony did in case of a flop. But as they say, what doesn’t kill you make you stronger; Nintendo took some of the Wii U’s best ideas and morphed into the Nintendo Switch – the rest is history.


GAME opens OUYA pre-orders in the UK, as the Android-powered console starts shipping to backers

But admittedly, the Wii U isn’t nearly as much of a flop as the Android-based Ouya was. What was supposed to be one of Kickstarter’s early success story ended up serving as proof that making a console is hard, especially if that console only costs $99. The system was plagued by problems and ultimately made nary a dent in the gaming industry.

Samsung Galaxy Note 7

samsung, galaxy note 7,

The Galaxy Note 7 was supposed to be one of the best phones of 2016. It seemed to do almost everything right, with innovative features, a gorgeous display, great battery life, and a sleek design given its large screen.

But then it started blowing up. A lot. Enough that the FAA banned the device from airplanes. Samsung had to issue what remains to date the largest recall of any tech product, even going as far as to issue an update that would forcibly prevent your phone from working.

On the plus side, nobody died, and Samsung got extra serious about its batteries. That’s something, I guess?

Project Ara

Project Ara
Credit: Google

Once upon a time, the future of smartphones wasn’t sleek, foldable devices and bezel-less displays. Instead, the future was comprised of modular phones that could be customized to your every whim.

At the forefront was the Lego-like Project Ara, a Google concept that would allow you to customize and upgrade your phones component-by-component.

Want a better display? Why, just change the display module. Care more about battery life than cameras? Sure, just add an extra battery module.

Unfortunately, the idea proved too complicated to roll out effectively. Save for the mild success of the Moto Z series, with the death of Project Ara so died the dream of modular phones.


Vine may not be dead thanks to a potential sale
Credit: Google

Another one for the social media graveyard, few ideas had as much of an impact as Vine’s 6.5-second-long videos did. It’s the reason Instagram does video, and it’s the reason TikTok exists.

Though Vine’s creators never quite figured out how to, you know, make money, the platform spawned countless memes and a community of creators that is still active on other platforms today. Short-lived as it may have been, Vine had an undeniable effect on the internet as we know it today.



For a brief moment in tech history, it seemed like Chinese company LeEco could have stood where Huawei is now. The company had a meteoric rise into the limelight, seeking to buy TV maker Vizio for $2 billion and bankrolling Faraday Future. It had been separately called the Tesla, Netflix, and Amazon of China. It even tried to break into the smartphone market with a media blitz in 2016.

And then it ran out of money and disappeared even more quickly than it showed up.

Faraday Future

Faraday Future unveils the world’s fastest electronic production car: ‘It’s faster ...

LeEco’s fall also meant the fall of what was once seen as the second most promising electric vehicle company, behind Tesla. But repeatedly broken promises, drama between executives, and a general cash crunch led to a company that’s now hanging on its last thread.


Review: The Key2 is the best BlackBerry phone. Ever.

You can’t fault BlackBerry for lack of effort, but once touchscreen keyboards better got better than hardware ones, the company didn’t really stand a chance.

Sure, BlackBerry tried to compete against Android and iOS for a while with BlackBerry 10, but eventually, it gave up and licensed the ‘BlackBerry Mobile’ brand to TCL to make Android Phones. Not even the once-ubiquitous BlackBerry Messenger survived its parent company’s downfall.


This $400 juicer that does nothing but squeeze juice packs is peak Silicon Valley

Remember that over-engineered $400 juice machine that literally did nothing except squeeze pre-made juice packs? The one that didn’t even work if it’s not connected to the internet? Yeah, its not around anymore.

Palm Pre and WebOS

Microsoft drops the seventh developer preview for IE9, claims it to be the world’s fastest browser ...

Oh Palm. Every time I write about the Palm Pre, my heart breaks a little for the potential embodied in the smartphone and its WebOS platform.

So much of modern smartphones were either copied from or inspired by webOS. Universal search, multitasking via ‘cards,’ OTA updates, gesture navigation, notifications management, web apps, and more were pioneered by Palm. But the hardware didn’t live up to the software.

HP bought WebOS and halfheartedly tried to make something of it, and now LG uses the software for its TVs. How the greats have fallen.


93e916f6051faf2f55e88f75e249c47d_original (1)

Another heartbreaker, Pebble’s original smartwatch was the first big Kickstarter success story. Unlike Coolest Cooler or Ouya, Pebble actually delivered honest-to-goodness impressive hardware over several generations. But it ultimately couldn’t make enough money to pay for its debt, due in part to a relatively lackluster reception to wearables in general at the time.

Still, Pebble paved the way for the popularity of devices like the Apple Watch and Fitbit Versa – the latter company which eventually acquired the ailing startup.


Apple cancels the AirPower wireless charging mat, citing quality issues

Once upon a time, Apple tried to make wirelessly charging three devices at once a thing. That didn’t happen.

Samsung Galaxy Fold (V1)

Galaxy Fold survives 60 percent of claimed folds in stress test, but that’s okay

Samsung’s Galaxy fold has been met with some positive reviews. But before it was a success, it was one of the most disastrous launches of all time.

This, of course, made worse by the fact it was also one of the most hyped phones of all time. But when the first batch of review units went out in the spring, the Galaxy Fold simply broke or stopped working for many early testers. Whether a speck of dust got caught in the hinge or the protective film atop the display was peeled off, it was clear the phone was too fragile for the prime time.

At least the Note 7 seemed to work for a while before it started to blow up. Luckily, Samsung got its act together and managed to launch it before the end of the year.

For more gear, gadget, and hardware news and reviews, follow Plugged on
Twitter and

Published December 28, 2019 — 10:00 UTC


The TypeScript 3.7 release is coming soon, and it’s going to be a big one.

The target release date is November 5th, and there’s some seriously exciting headline features included:

  • Assert signatures
  • Recursive type aliases
  • Top-level await
  • Null coalescing
  • Optional chaining

Personally, I’m super excited about this, they’re going to whisk away all sorts of annoyances that I’ve been fighting in TypeScript whilst building HTTP Toolkit.

If you haven’t been paying close attention to the TypeScript development process though, it’s probably not clear what half of these mean, or why you should care. Let’s talk them through.

Assert Signatures

This is a brand-new & little-known TypeScript feature, which allows you to write functions that act like type guards as a side-effect, rather than explicitly returning their boolean result.

It’s easiest to demonstrate this with a JavaScript example:

function assertString(input) {
    if (typeof input === 'string') return;
    else throw new Error('Input must be a string!');

function doSomething(input) {



This pattern is neat and useful and you can’t use it in TypeScript today.

TypeScript can’t know that you’ve guaranteed the type of input after it’s run assertString. Typically people just make the argument input: string to avoid this, and that’s good, but that also just pushes the type checking problem somewhere else, and in cases where you just want to fail hard it’s useful to have this option available.

Fortunately, soon we will:

function assertString(input: any): asserts input is string { 
    if (typeof input === 'string') return;
    else throw new Error('Input must be a string!');

function doSomething(input: string | number) {


Here assert input is string means that if this function ever returns, TypeScript can narrow the type of input to string, just as if it was inside an if block with a type guard.

To make this safe, that means if the assert statement isn’t true then your assert function must either throw an error or not return at all (kill the process, infinite loop, you name it).

That’s the basics, but this actually lets you pull some really neat tricks:

function assert(input: any): asserts input { 
    if (!input) throw new Error('Not a truthy value');

declare const x: number | string | undefined;

assert(typeof x === 'string'); 

const a: Result | Error = doSomethingTestable();


function assertDefined<T>(obj: T): asserts obj is NonNullable<T> {
    if (obj === undefined || obj === null) {
        throw new Error('Must not be a nullable value');
declare const x: string | undefined;

const y = x!;

const z = x;

type X<T extends string | {}> = { value: T };

function setX<T extends string | {}>(x: X<any>, v: T): asserts x is X<T> {
    x.value = v;

declare let x: X<any>; 

setX(x, 123);

This is still in flux, so don’t take it as the definite result, and keep an eye on the pull request if you want the final details.

There’s even discussion there about allowing functions to assert something and return a type, which would let you extend the final example above to track a much wider variety of side effects, but we’ll have to wait and see how that plays out.

Top-level Await

Async/await is amazing, and makes promises dramatically cleaner to use.

Unfortunately though, you can’t use them at the top level. This might not be something you care about much in a TS library or application, but if you’re writing a runnable script or using TypeScript in a REPL then this gets super annoying. It’s even worse if you’re used to frontend development, since top-level await has been working nicely in the Chrome and Firefox console for a couple of years now.

Fortunately though, a fix is coming. This is actually a general stage-3 JS proposal, so it’ll be everywhere else eventually too, but for TS devs 3.7 is where the magic happens.

This one’s simple, but let’s have another quick demo anyway:

async function doEverything() {
    const response = await fetch('');

With top-level await:

const response = await fetch('');

There’s a notable gotcha here: if you’re not writing a script, or using a REPL, don’t write this at the top level, unless you really know what you’re doing!

It’s totally possible to use this to write modules that do blocking async steps when imported. That can be useful for some niche cases, but people tend to assume that their import statement is a synchronous, reliable & fairly quick operation, and you could easily hose your codebase’s startup time if you start blocking imports for complex async processes (even worse, processes that can fail).

This is somewhat mitigated by the semantics of imports of async modules: they’re imported and run in parallel, so the importing module effectively waits for Promise.all(importedModules) before being executed. Rich Harris wrote an excellent piece on a previous version of this spec, before that change, when imports ran sequentially and this problem was much worse), which makes for good background reading on the risks here if you’re interested.

It’s also worth noting that this is only useful for module systems that support asynchronous imports. There isn’t yet a formal spec for how TS will handle this, but that likely means that a very recent target configuration, and either ES Modules or Webpack v5 (whose alphas have experimental support) at runtime.

Recursive Type Aliases

If you’re ever tried to define a recursive type in TypeScript, you may have run into StackOverflow questions like this:

Right now, you can’t. Interfaces can be recursive, but there are limitations to their expressiveness, and type aliases can’t. That means right now, you need to combine the two: define a type alias, and extract the recursive parts of the type into interfaces. It works, but it’s messy, and we can do better.

As a concrete example, this is the suggested type definition for JSON data:

type JSONValue =
    | string
    | number
    | boolean
    | JSONObject
    | JSONArray;

interface JSONObject {
    [x: string]: JSONValue;

interface JSONArray extends Array<JSONValue> { }

That works, but the extra interfaces are only there because they’re required to get around the recursion limitation.

Fixing this requires no new syntax, it just removes that restriction, so the below compiles:

type JSONValue =
    | string
    | number
    | boolean
    | { [x: string]: JSONValue }
    | Array<JSONValue>;

Right now that fails to compile with Type alias 'JSONValue' circularly references itself. Soon though, soon…

Null Coalescing

Aside from being difficult to spell, this one is quite simple & easy. It’s based on a JavaScript stage-3 proposal, which means it’ll also be coming to your favourite vanilla JavaScript environment too soon, if it hasn’t already.

In JavaScript, there’s a common pattern for handling default values, and falling back to the first valid result of a defined group. It looks something like this:

const result = firstResult || secondResult;

this.configValue = options.configValue || 'default';

This is useful in a host of cases, but due to some interesting quirks in JavaScript, it can catch you out. If firstResult or options.configValue can meaningfully be set to false, an empty string or 0, then this code has a bug. If those values are set, then when considered as booleans they’re falsy, so the fallback value (secondResult / 'default') is used anyway.

Null coalescing fixes this. Instead of the above, you’ll be able to write:

const result = firstResult ?? secondResult;

this.configValue = options.configValue ?? 'default';

?? differs from || in that it falls through to the next value only if the first argument is null or undefined, not falsy. That fixes our bug. If you pass false as firstResult, that will be used instead of secondResult, because while it’s falsy it is still defined, and that’s all that’s required.

Simple, but super useful, and takes a way a whole class of bugs.

Optional Chaining

Last but not least, optional chaining is another stage-3 proposal which is making its way into TypeScript.

This is designed to solve an issue faced by developers in every language: how do you get data out of a data structure when some or all of it might not be present?

Right now, you might do something like this:

let result = data ? (data.key1 ? data.key1.key2 : undefined) : undefined;

let result = ((data || {}).key1 || {}).key2;

Nasty! This gets much much worse if you need to go deeper, and although the 2nd example works at runtime, it won’t even compile in TypeScript since the first step could be {}, in which case key1 isn’t a valid key at all.

This gets still more complicated if you’re trying to get into an array, or there’s a function call somewhere in this process.

There’s a host of other approaches to this, but they’re all noisy, messy & error-prone. With optional chaining, you can do this:

let result = data?.key1?.key2;



let result = data?.key1?.key2 ?? 'default';

The last case shows how neatly some of these dovetail together: null coalescing optional chaining is a match made in heaven.

One gotcha: this will return undefined for missing values, even if they were null, e.g. in cases like (null)?.key (returns undefined). A small point, but one to watch out for if you have a lot of null in your data structures.

That’s the lot! That should outline all the essentials for these features, but there’s lots of smaller improvements, fixes & editor support improvements coming too, so take a look at the official roadmap if you want to get into the nitty gritty.

Hope that’s useful – if you’ve got any questions let me know on Twitter.

While you’re here, if you like JavaScript & want to supercharge your debugging skills, try out HTTP Toolkit. One-click HTTP(S) interception & debugging for any JS page, script, or server (plus lots of other tools too).