Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot import type definitions from @sendgrid/mail #674

Closed
killtheliterate opened this issue Apr 5, 2018 · 9 comments
Closed

Cannot import type definitions from @sendgrid/mail #674

killtheliterate opened this issue Apr 5, 2018 · 9 comments
Labels
difficulty: unknown or n/a fix is unknown in difficulty status: help wanted requesting help from the community type: question question directed at the library

Comments

@killtheliterate
Copy link

killtheliterate commented Apr 5, 2018

Issue Summary

I cannot import and use the type definitions from @sendgrid/mail with TS v2.8.1. Very likely that I've just misunderstood, but have tried a few things after reading the index.d.ts.

Seems the type I would like is MailService & { MailService: MailService; }, so says tsc if I try to arbitrarily assert something like:

SendGrid.setApiKey('blahblah')
export default Sendgrid as SomethingElse

Steps to Reproduce

Doesn't work:

import SendGrid = require('@sendgrid/mail')

interface Foo {
  mail: Sendgrid.MailService // [ts] Cannot find namespace 'Sendgrid'
}

Also doesn't work:

import { MailService } from '@sendgrid/mail'

interface Foo {
  mail: MailService // [ts] Cannot find name 'MailService'
}

Technical details:

  • sendgrid-nodejs: v6.2.1
  • typescript: v2.8.1
  • node: v9.6.1

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "./",
    "module": "commonjs",
    "outDir": "dist",
    "sourceMap": true,
    "strict": true,
    "target": "es6",

    "paths": {
      "@/*": ["src/*"]
    }
  }
}

Mentioned this in #476 - thought it might be related.

@thinkingserious
Copy link
Contributor

@spartan563,

Any ideas?

@thinkingserious thinkingserious added type: question question directed at the library status: help wanted requesting help from the community up-for-grabs difficulty: unknown or n/a fix is unknown in difficulty labels Apr 9, 2018
@notheotherben
Copy link
Contributor

Hi @killtheliterate,

Can you let me know if this works for you?

import * as SendGrid from "@sendgrid/mail";
SendGrid.setApiKey("blahblah")

interface Foo {
    mail: typeof SendGrid.MailService
}

const foo: Foo = {
    mail: SendGrid
}

export = foo

It appears to work fine locally for me, the big difference being the use of the typeof keyword when referencing the MailService type within your interface.

@killtheliterate
Copy link
Author

@spartan563 that does the trick, thank you! Is there a link you could toss me that explains why the typeof is necessary?

@notheotherben
Copy link
Contributor

Great!

The reason why the original version ({ mail: SendGrid.MailService }) doesn't work is that you're attempting to treat a value as a type. The typeof operator transforms that value into a type which can then be used within the type system to build the constraint you're looking for.

Take the following example:

const X = {
  x: String
}

interface Y {
  y: X.x
}

Looking at that, you'd probably expect it not to work since you're trying to constrain a type based on the value of a const object ({ x: String }). However to accomplish what is implied by that example, you could ask TypeScript to constrain based on the type of the value, in this case:

const X = {
  x: String
}

interface Y {
  y: typeof X.x // String
}

Exactly the same thing is at play here due to the gymnastics we had to perform to represent the library's interface in TypeScript. Unfortunately libraries that make use of the old NodeJS module.exports = X export format will continue to encounter problems like this and while we can work around it with virtual namespaces and XConstructor interfaces, it generally isn't worth it and leads to even more confusion.

I hope that explains what's going on and why, but please feel free to ask if you've got any other questions or if my explanation isn't clear.

@killtheliterate
Copy link
Author

@spartan563 thanks so much for the explanation!

@dougadriquei
Copy link

Good evening,

My app is on firebase (node.js), and I had the same problem.

I changed the way I imported @sendgrid

I also set up single sender verification on app.sendgrid.com.

Before:
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(SENDGRID_API_KEY);

After:
import * as SendGrid from "@sendgrid/mail";
const SENDGRID_API_KEY = functions.config().sendgrid.key

SendGrid.send(msg).then( snapshotMail => {
  console.log("Passou D")
  console.log("Sucesso")
  console.log(snapshotMail[0])
  console.log(snapshotMail[1])
}).catch((e)=> console.error(e.message));

@JakubKoralewski
Copy link

JakubKoralewski commented Jul 7, 2020

@dougadriquei I'm having the same problem, but import * as SendGrid from "@sendgrid/mail"; doesn't work for me and results in TypeError: s.setApiKey is not a function. So I have to use import SendGrid ... normally, and when console.logging the functions are there as expected.
I'm on CloudFlare workers. It works on Nodejs as expected 😕

According to SendGrid's docs Single Sender Verification doesn't apply to me.

Turns out import * as doesn't matter it's just peculiarity of esModuleInterop being set to true, once set back to false and import being import * as it still doesn't work 😕

@andreidiaconescu
Copy link

andreidiaconescu commented Jul 9, 2021

Hello
As @JakubKoralewski reported
import * as SendGrid from "@sendgrid/mail";
does not work as it produces an error.
SendGrid.setApiKey(...)
produces:
TypeError: s.setApiKey is not a function

How could i use it in Typescript ?

thank you

@andreidiaconescu
Copy link

i found the solution:

import SendGrid from '@sendgrid/mail';
then
SendGrid.setApiKey(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty: unknown or n/a fix is unknown in difficulty status: help wanted requesting help from the community type: question question directed at the library
Projects
None yet
Development

No branches or pull requests

7 participants