You can achieve what you want without the instanceof keyword as you can write custom type guards now:

interface A {
    member: string;
}

function instanceOfA(object: any): object is A {
    return 'member' in object;
}

var a: any = {member: "foobar"};

if (instanceOfA(a)) {
    alert(a.member);
}

Lots of Members

If you need to check a lot of members to determine whether an object matches your type, you could instead add a discriminator. The below is the most basic example, and requires you to manage your own discriminators... you'd need to get deeper into the patterns to ensure you avoid duplicate discriminators.

interface A {
    discriminator: 'I-AM-A';
    member: string;
}

function instanceOfA(object: any): object is A {
    return object.discriminator === 'I-AM-A';
}

var a: any = {discriminator: 'I-AM-A', member: "foobar"};

if (instanceOfA(a)) {
    alert(a.member);
}
Answer from Fenton on Stack Overflow
🌐
DEV Community
dev.to › lico › typescript-checking-type-of-value-interface-and-type-4dn8
Typescript: Checking Type of a Value, (interface, type) - DEV Community
November 2, 2022 - Typescript: Checking Type of Value, Interface and Type · Let's say there are animal types and instances of them. interface Cat { catId: number; } interface Dog { dogId: number; } type Bird = { birdId: number; }; const cat: Cat = { catId: 1 }; const dog: Dog = { dogId: 1 }; const bird: Bird = { birdId: 1 }; Then, how do you check the type of the instances? With typeof ·
Discussions

typeof usage in interface
When you use typeof in a type position (like in an interface, type annotation etc.), it gives you the TypeScript type of the item (in build time). When you use it as an expression to run the code, it'll print the runtime type (which is 'string'). A better equivalent would be to hover over the GET_ALL variable in your code editor to see the type rather than running the code. typeof is basically an overloaded operator which means different things in runtime and in types. TypeScript doesn't exist in runtime, it's compiled away. It's a build-time only thing (mostly). You can't console.log build-time types. More on reddit.com
🌐 r/typescript
10
8
January 11, 2021
javascript - Interface type check with Typescript
This question is the direct analogon to Class type check in TypeScript I need to find out at runtime if a variable of type any implements an interface. Here's my code: interface A { member: str... More on stackoverflow.com
🌐 stackoverflow.com
typing - Is there a way to "extract" the type of TypeScript interface property? - Stack Overflow
Therefore, is there any way to ... of the interface? Something similar to let myVar: typeof I2.y (which doesn't work and results in "Cannot find name I2" error). Edit: after playing a bit in TS Playground I noticed that following code achieves exactly what I want to: ... However it requires a redundant variable x to be declared. I am looking for a way to achieve this without that declaration. ... It wasn't possible before but luckily it is now, since TypeScript version ... More on stackoverflow.com
🌐 stackoverflow.com
Interfaces vs Types in TypeScript - Stack Overflow
/** * When FirstLevelType is type ... = typeof a extends FirstLevelType ? T : "not extended"; ... That's the biggest practical difference imho - an interface will never be assignable to Record 2023-07-25T14:31:05.6Z+00:00 ... @maciejkravchyk exactly, Record is technically a primitive which is only assignable to a type 2025-01-05T23:21:17.687Z+00:00 ... In typescript, "interface" ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
LogRocket
blog.logrocket.com › home › types vs. interfaces in typescript
Types vs. interfaces in TypeScript - LogRocket Blog
December 18, 2025 - Type aliases can be created using the type keyword, referring to any valid TypeScript type, including primitive types: type MyNumber = number; type User = { id: number; name: string; email: string; } In the above example, we create two type aliases: MyNumber and User. We can use MyNumber as shorthand for a number type and use User type aliases to represent the type definition of a user. When we say “types versus interfaces,” we refer to “type aliases versus interfaces.” For example, you can create the following aliases:
🌐
Reddit
reddit.com › r/typescript › typeof usage in interface
r/typescript on Reddit: typeof usage in interface
January 11, 2021 -

Hello everyone I'm learning TypeScript and today and come over a piece of code that puzzled me

const GET_ALL = "get_all";

console.log(typeof GET_ALL);

This, if run, will print out string as output. This is expected.

However, if I try to use the variable like below, the result is that it become string literal

interface fetchAllNotesAction {
  name: typeof GET_ALL;
}

Now the name type is the "get_all" (string literal) and not "string". Why does TypeScript return two different type on these cases?

Top answer
1 of 4
5
When you use typeof in a type position (like in an interface, type annotation etc.), it gives you the TypeScript type of the item (in build time). When you use it as an expression to run the code, it'll print the runtime type (which is 'string'). A better equivalent would be to hover over the GET_ALL variable in your code editor to see the type rather than running the code. typeof is basically an overloaded operator which means different things in runtime and in types. TypeScript doesn't exist in runtime, it's compiled away. It's a build-time only thing (mostly). You can't console.log build-time types.
2 of 4
3
Building off of u/satya164 's comment's technical explanation. (TDLR; is that typeof in the Javascript of console logging is different from Typescript's typeof when defining a type.) Let's dig into why Typescript says that typeof GET_ALL is equal to the string literal itself. When you tell TS that you want name to be typeof GET_ALL, Typescript makes a promise to you that it will absolutely always be possible to pass name into a variable or function where you could pass GET_ALL. But, since Typescript allows you to define string literal values like "get_all" as a type (which btw is how it enums work), and since it knows that GET_ALL is a const which will always have the same string value, it determines that the type for name should also be the string literal "get_all". Here's an example that shows why typeof GET_ALL has to be the string literal to keep that promise: // Some function that takes the string literal type as its input. const printGetAll = (constantValue: "get_all") => { console.log(constantValue); } // This works because TS knows that this constant will have the right value printGetAll(GET_ALL); // This also works, because the typeof GET_ALL guarantees that anywhere // you could use GET_ALL, you can use someString... let someString: typeof GET_ALL = "get_all"; printGetAll(someString); // But, this line fails. If you were allowed to do this, then you would // no longer be able to use someString everywhere you can use GET_ALL, // which means it would no longer have the type of GET_ALL. someString = "William"; // Type error "William" is not assignable to... // And this wouldn't work because the input no longer is the value we expect printGetAll(someString); The easiest way for you to work around this is to give GET_ALL an explicit type - either string to be maximally generic, or an enum type if you want to limit it to a set of values.
Top answer
1 of 16
581

You can achieve what you want without the instanceof keyword as you can write custom type guards now:

interface A {
    member: string;
}

function instanceOfA(object: any): object is A {
    return 'member' in object;
}

var a: any = {member: "foobar"};

if (instanceOfA(a)) {
    alert(a.member);
}

Lots of Members

If you need to check a lot of members to determine whether an object matches your type, you could instead add a discriminator. The below is the most basic example, and requires you to manage your own discriminators... you'd need to get deeper into the patterns to ensure you avoid duplicate discriminators.

interface A {
    discriminator: 'I-AM-A';
    member: string;
}

function instanceOfA(object: any): object is A {
    return object.discriminator === 'I-AM-A';
}

var a: any = {discriminator: 'I-AM-A', member: "foobar"};

if (instanceOfA(a)) {
    alert(a.member);
}
2 of 16
174

In TypeScript 1.6, user-defined type guard will do the job.

interface Foo {
    fooProperty: string;
}

interface Bar {
    barProperty: string;
}

function isFoo(object: any): object is Foo {
    return 'fooProperty' in object;
}

let object: Foo | Bar;

if (isFoo(object)) {
    // `object` has type `Foo`.
    object.fooProperty;
} else {
    // `object` has type `Bar`.
    object.barProperty;
}

And just as Joe Yang mentioned: since TypeScript 2.0, you can even take the advantage of tagged union type.

interface Foo {
    type: 'foo';
    fooProperty: string;
}

interface Bar {
    type: 'bar';
    barProperty: number;
}

let object: Foo | Bar;

// You will see errors if `strictNullChecks` is enabled.
if (object.type === 'foo') {
    // object has type `Foo`.
    object.fooProperty;
} else {
    // object has type `Bar`.
    object.barProperty;
}

And it works with switch too.

🌐
TypeScript
typescriptlang.org › docs › handbook › utility-types.html
TypeScript: Documentation - Utility Types
Beyond being recognized in the contextual type of an object literal, the interface acts like any empty interface. To help with string manipulation around template string literals, TypeScript includes a set of types which can be used in string manipulation within the type system.
Find elsewhere
🌐
Tim Mousk
timmousk.com › blog › typescript-instanceof-interface
How To Use InstanceOf On An Interface In TypeScript? – Tim Mouskhelichvili
March 6, 2023 - Unfortunately, you cannot use the instanceOf keyword on an interface in TypeScript.
🌐
Tutorial Teacher
tutorialsteacher.com › typescript › typescript-interface
TypeScript Interfaces
In the above example, an interface KeyPair includes two properties key and value. A variable kv1 is declared as KeyPair type. So, it must follow the same structure as KeyPair. It means only an object with properties key of number type and value of string type can be assigned to a variable kv1. The TypeScript compiler will show an error if there is any change in the name of the properties or the data type is different than KeyPair.
🌐
Codecademy
codecademy.com › learn › learn-typescript › modules › learn-typescript-advanced-object-types › cheatsheet
Learn TypeScript: Advanced Object Types Cheatsheet | Codecademy
To create an interface, use the interface keyword followed by the interface name and the typed object. ... In TypeScript, type aliases can define composite types such as objects and unions as well as primitive types such as numbers and strings; ...
Top answer
1 of 16
2181

2019 Update


The current answers and the official documentation are outdated. And for those new to TypeScript, the terminology used isn't clear without examples. Below is a list of up-to-date differences.

 1. Objects / Functions

Both can be used to describe the shape of an object or a function signature. But the syntax differs.

Interface

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

Type alias

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

 2. Other Types

Unlike an interface, the type alias can also be used for other types such as primitives, unions, and tuples.

// primitive
type Name = string;

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

 3. Extend

Both can be extended, but again, the syntax differs. Additionally, note that an interface and type alias are not mutually exclusive. An interface can extend a type alias, and vice versa.

Interface extends interface

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

Type alias extends type alias

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

Interface extends type alias

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

Type alias extends interface

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

 4. Implements

A class can implement an interface or type alias, both in the same exact way. Note however that a class and interface are considered static blueprints. Therefore, they can not implement / extend a type alias that names a union type.

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

 5. Declaration merging

Unlike a type alias, an interface can be defined multiple times, and will be treated as a single interface (with members of all declarations being merged).

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };
2 of 16
1336

Update March 2021: The newer TypeScript Handbook (also mentioned in nju-clc answer below) has a section Interfaces vs. Type Aliases which explains the differences.


Original Answer (2016)

As per the (now archived) TypeScript Language Specification:

Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind of type, including primitive, union, and intersection types.

The specification goes on to mention:

Interface types have many similarities to type aliases for object type literals, but since interface types offer more capabilities they are generally preferred to type aliases. For example, the interface type

interface Point {
    x: number;
    y: number;
}

could be written as the type alias

type Point = {
    x: number;
    y: number;
};

However, doing so means the following capabilities are lost:

  • An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot No longer true since TS 2.7.
  • An interface can have multiple merged declarations, but a type alias for an object type literal cannot.
🌐
GeeksforGeeks
geeksforgeeks.org › how-to-check-interface-type-in-typescript
How to check interface type in TypeScript ? - GeeksforGeeks
September 29, 2020 - How to check interface type in TypeScript ? B · bunnyram19 · Follow · Improve · Article Tags : JavaScript · Web Technologies · TypeScript · How to Check Types in Typescript? Checking types in TypeScript involves methods like typeof for primitive types, instanceof for class instances, and custom type guards for complex type validation.
🌐
Simon Dosda
simondosda.github.io › posts › 2021-06-17-interface-property-type.html
Getting The Type Of An Interface Property In Typescript | Simon Dosda
July 21, 2021 - Currently, Typescript considers it as any as we don’t provide any type hint, which gives us the error Type 'any' is not assignable to type 'never'. when we try to update our property.
🌐
Maya Shavin
mayashavin.com › articles › types-from-constants-typescript
Using keyof and typeof for types efficiently in TypeScript
February 15, 2023 - Additionally, we can use typeof in TypeScript to act as the type guard within a conditional block, just like in JavaScript, though in this case, it will mainly work for primitive types like string, object, function, etc... Now we understand typeof and its usage. Next, we will explore keyof. While typeof produces the type represented by a variable, keyof takes an object type and produces a type that is the liberal union of that variable's keys, as seen below: interface User { firstName: string; lastName: string; }; type UserKeys = keyof User
🌐
Bitstack
blog.bitsrc.io › how-to-use-keyof-typeof-in-typescript-de453fa04fef
How to Use 'keyof' 'typeof' in TypeScript | Bits and Pieces
March 4, 2025 - Before getting into the sorting function, let’s review the basics of keyof and typeof in TyepScript. TypeScript typeof returns a type of variable or property.
🌐
Total TypeScript
totaltypescript.com › type-vs-interface-which-should-you-use
Type vs Interface: Which Should You Use? | Total TypeScript
December 18, 2023 - Matt PocockMatt is a well-regarded TypeScript expert known for his ability to demystify complex TypeScript concepts. ... You should use types by default until you need a specific feature of interfaces, like 'extends'.
🌐
Reddit
reddit.com › r/typescript › getting interface property type
r/typescript on Reddit: Getting interface property type
April 10, 2021 -
interface A {
  num: number;
}

consolelog(A['num']);

A senior engineer interviewing me told me the above should log the type for that property, as a string, but it does not in my testing.

Is something missing? Or is this not at all possible? I thought because types are wiped out at compile time this type of type accessing was not possible.

🌐
DEV Community
dev.to › worldpwn › typescript-instanceof-interface-is-it-possible-5flk
TypeScript 'instanceof' interface is it possible? - DEV Community
January 3, 2022 - Because types do not exist in runtime. There is no such thing as an interface in JavaScript. We can use string literal types in TypeScript to identify the interface.