Reputation: 139
Consider this class:
import type { PublishCommand, SNSClient } from '@aws-sdk/client-sns'
export class MyPublisher {
private readonly topicArn: string
private readonly snsClient: SNSClient
constructor(topicArn: string, snsClient: SNSClient) {
this.topicArn = topicArn
this.snsClient = snsClient
}
async publish(title = '', description = '', Foo: PublishCommand) {
return this.snsClient.send(
new Foo({
Message: JSON.stringify({
version: '1.0',
source: 'custom',
content: {
description,
title,
},
}),
TopicArn: this.topicArn,
}),
)
}
}
With TypeScript 5 it generates the error "This expression is not constructable." where I try to instantiate with "new Foo()". But if I add typeof just before the type of the argument Foo, it works:
import type { PublishCommand, SNSClient } from '@aws-sdk/client-sns'
export class MyPublisher {
private readonly topicArn: string
private readonly snsClient: SNSClient
constructor(topicArn: string, snsClient: SNSClient) {
this.topicArn = topicArn
this.snsClient = snsClient
}
async publish(title = '', description = '', Foo: typeof PublishCommand) {
return this.snsClient.send(
new Foo({
Message: JSON.stringify({
version: '1.0',
source: 'custom',
content: {
description,
title,
},
}),
TopicArn: this.topicArn,
}),
)
}
}
Can someone explain to me why is that? Since I'm already importing the types only. Does it even mean something to typeof a type?
Upvotes: 0
Views: 50
Reputation: 1342
Anything of type PublishCommand already is an object. That is to say it has already been instantiated. Your first example is like attempting to call new 123()
or new "Hello World"()
. If you are trying to make a new PublishCommand, you can simply call new PublishCommand(...)
. It's unclear what else you would be attempting to do with this code.
To answer your question directly, PublishCommand, as a class (not just a type), is considered to have the type of function
. This means that when you pass something with the same type as PublishCommand, it is also a function
, and you can construct one with the new
keyword
Upvotes: 0
Reputation: 1196
It seem that PublishCommand
is a class. Classes in TypeScript are a bit special, since they are both type and value at same time. Type PublishCommand
refers to instance of class, object which you get by executing new PublishCommand()
, while value PublishCommand
is constructor.
And when you try to get type of value (by using typeof
) you get type for constructor, not for the instance.
Consider this code (playground):
class Beep {};
type A = Beep;
type B = typeof Beep;
const a: A = new Beep();
const b: B = Beep;
Here A
refers to type of instance of class Beep
, while B
refers to type of constructor itself.
But it's indeed seems a bit odd, that you can use typeof
with PublishCommand
even if you imported only type.
Upvotes: 0