In the example you provided, the use of var
is part of a pair with interface
that TypeScript standard libraries utilize to define built-in stuff like classes in TypeScript.
There are two instances of Request
in your example. One represents the actual value - a var
expected to exist during runtime. The other depicts the type - an erased interface
that will not exist at runtime when compiled into JavaScript. These distinctions can be identified by their different syntactic contexts; for instance, if you encounter declare var x: Y
, where x
is the value name and Y
is the type name.
This kind of declaration is common in TypeScript standard libraries as it mimics class declarations. When you declare something like:
declare class Foo {
a: string;
b: number;
constructor(a: string, b: number);
}
Both a value and a type named Foo
come into play. The value represents the Foo
constructor, allowing you to create instances such as new Foo("abc", 123)
. On the other hand, the type signifies the type of Foo
instances, akin to an interface like {a: string, b: number}
. Having them share the same name enables developers to write code like
const foo: Foo = new Foo("abc", 123)
.
The standard libraries of TypeScript usually avoid using class
due to backward compatibility and edge case reasons. Instead they employ a var
/interface
paired declaration approach:
interface Foo {
a: string;
b: number;
}
declare var Foo: {
prototype: Foo;
new(a: string, b: number): Foo;
}
This method achieves similar functionality as declaring a class explicitly but brings the type and value separately into scope. The value Foo
serves as a variable with a construct signature while the interface Foo
represents the instance type.
You can perform all operations with the var
/interface
pair just like with class
. The following code behaves identically:
const foo = new Foo("abc", 123);
foo.a.toUpperCase();
foo.b.toFixed();
By examining the TypeScript library definitions for Request
, you'll notice an associated interface
. This could be restructured as follows:
declare class Request {
new(input: RequestInfo | URL, init?: RequestInit): Request;
readonly body: ReadableStream<Uint8Array> | null;
// More properties...
clone(): Request;
}
and would function similarly.
Playground link for code examples