It's called TypeScript not InterfaceScript
If you're a purist like I am, you know the debate between 'interface vs. type' can be frustrating. Why is there no official stance on this issue?
I've been using Ts since 2015 and I've been through different phases.
First, I encouraged using interfaces instead of types (unless an Union/Intersection was needed);
...then I reached the stable plateau of "whichever you prefer, it doesn't matter" π.
Till now.
For some time I've been using the type "Any key-value object" a.k.a Record<string, unknown>
If you type something as any key-value object;
function foo(data: Record<string, unknown>) {
for (const [key, value] of Object.entries(data)) {
// ...
}
}
You might reach a dead end if you use interface
:
interface Profile {
name: string;
}
function getProfile(): Profile {
/* fetch data */
return Promise.resolve({ name: 'jane' });
}
...
const profile = await getProfile()
foo(profile); // ERROR β
// Argument of type 'Profile' is not assignable to parameter of type
// 'Record<string, unknown>'.
// Index signature for type 'string' is missing in type
// 'Profile'.ts(2345)
Our interface { name: string }
does NOT fulfill Record<string, unknown>
.
I respectful disagree? with typescript here π€
Now, let's change the thing to type
instead:
function foo(data: Record<string, unknown>) {
for (const [key, value] of Object.entries(data)) {
// ...
}
}
type Profile = {
name: string;
};
function getProfile(): Profile {
/* fetch data */
return Promise.resolve({ name: 'jane' });
}
...
const profile = await getProfile()
foo(profile); // β
nice
π The type { name: string }
does fulfill Record<string, unknown>
This type of situation isn't specific to Record<string, unknown>
' but I don't want to research which Advanced types will work and which won't. So, I've turned to using types -almost- exclusively."
I was shocked to find out that Matt Pocock also went through the same three phases!.
If you haven't heard of Matt, I highly recommend checking him out. He creates high-quality TypeScript content on Youtube (and is a nice guy on Twitter π¦).
TL;DR: prefer types to interfaces, people on the internet defend types.
Top comments (6)
Great artigo, π thanks for exposing this!
I'm glad to see I'm not the only one that thinks typescript isn't very consistent in some cases.
Glad you liked it. I expect they 'fix' this specific issue eventually TBH. Doens't make sense that
{ key: value }
can't be infered as a pair "key - value" xDTotally agree, itβs very frustrating that the language has these two concepts that are so similar that no one knows which one to use and thereβs very little guidance.
I usually used
any
instead ofunknown
and just ran into this due to an eslint configuration. I really only use theany
when building something like logging where we don't really care about the majority of what's on an object.An alternative is to extend the type on your interfaces, if you want to avoid the index signature.
I still prefer interfaces for various reasons, but number 1 is to make the intellisense easier to read. Instead of seeing 20 field definitions with a
...
at the end (not helpful), I can actually see the interface nameProfile
. Try reading things like supabase-generated types at a glance and it's painful.I've settled on using interfaces when writing OOP typescript and types in all other circumstances, but I don't have more specific motivation, just that interfaces feel more OOPish π
Another video from Matt:
Types vs Interfaces: What I Got Wrong In 2022
youtube.com/watch?v=e0AIkYrXAYE