While this may look like a perfectly good type signature and implementation, when we consider the usability of the
returned value's type, there are going to be some surprises—especially in TypeScript's --strict mode.

For this example, let's assume we have the following interface:

interface MyStruct {
str: string;
num: number;
bool: boolean;
}

If we use this naive version of pluck, we'll see that there are some unexpected consequences of type inference.

If we wanted API usability/behavior to act a certain way at runtime, we could write a few tests which assert that
behavior and then modify our implementation of pluck so that our desired behavior is verified. However, since the
behavior we want is something that is determined at compile-time, we need to resort to telling the compiler to
perform these assertions for us at compile-time.

Using TypeScript 2.8's conditional types, we can define the shape and inference behavior of the API we want to build
prior to actually implementing it. Think of this as a sort of TDD for your types.

We can do this by (1) asserting the inferred value is assignable to the types that we want (conditional types come
in handy here), and (2) cause the compiler to reject code at compile time when these assertions are not true.

As a tiny example, if we want to write a compile-time test that asserts "this value should really be inferred as a
number," we can do the following:

This compiles, which means our problem #1 is solved! Unfortunately, this signature is a lie. While we "fixed" #1, we
still need to deal with our case #2, where missing members are still present in the returned type.

To check for this, we need a few type devices to fail compile if a key is present in a type:

When we have automated tests which assert the behavior of our code, we gain confidence that changes to our software will
not introduce regressions. However, when designing an API which is meant to leverage type inference to gain usability,
there hasn't really been an obvious way of doing this.

This technique allows us to effectively test how TypeScript performs its inference for users of our API. We can
build a test module which makes assertions about our desired type inference, and if the test file compiles successfully,
our assertions are correct! That way, if our API subtly changes in a way that makes return values or callback parameters
harder to infer, we can be alerted to this by a failure to compile.

If you happen to know of other techniques that can be used to accomplish this sort of compile-time assertion, I'd love
to hear them! Please reach out and let me know!

Do you want to learn more? Was something confusing? Was something insightful? In the NYC area
and want to grab a coffee? Feel free to drop me an email at
sufian@gmail.com or send a tweet my way
@sufianrhazi

Disclaimer: Unless stated otherwise, the above words are my own and do not represent the
opinions of any person or business but myself.