Hi folks, I'm struggling with consuming d.ts defin...
# javascript
p
Hi folks, I'm struggling with consuming d.ts definitions generated by
jsGenerateExternals
from within TypeScript. A minimal example: my d.ts file starts like this
Copy code
type Nullable<T> = T | null | undefined
export namespace com.example.myproject {
    class CoolDto {
        constructor(isDog: string);
        readonly isDog: string;
        // ...
and in TS I import it like this:
Copy code
import { com } from '../../sharedModel';

const { CoolDto } = com.example.myproject;
type CoolDto = typeof CoolDto;
and then simply use it this way:
Copy code
coolDtoInstance.isDog
but IntelliJ and TS compiler are complaining:
Copy code
Property 'isDog' does not exist on type 'typeof CoolDto'.  TS2339

    73 | 
  > 74 |   const isDog = coolDtoInstance.isDog;
       |                                 ^
The funny thing is that IntelliJ hints to add this field to this d.ts file, but after adding it, it still doesn't work 😕 Any ideas?
✅ 1
youtrack 1
d
What does the corresponding Kotlin code look like?
p
Copy code
package com.example.myproject

import kotlinx.serialization.Serializable
import kotlin.js.ExperimentalJsExport
import kotlin.js.JsExport

@Serializable
@JsExport
@ExperimentalJsExport
data class CoolDto(
    val isDog: String
)
d
You could try annotating
isDog
with
@JsName("isDog")
You could also check the output JS to see what the compiler is actually generating
p
Adding
@JsName(...)
doesn't change anything 😞 the first code snippet is what the Kotlin compiler generates. I realized it's not really a Kotlin problem (đŸ˜¶), but consuming some
d.ts
file from TypeScript. If we get this to work, next we can think if Kotlin correctly generates
d.ts
d
Oh wait, how come you're u sing
typeof CoolDto
? You should be able to just use
CoolDto
as-is
p
I thought the same, but then then I'm getting
Copy code
TS2749: 'CoolDto' refers to a value, but is being used as a type here. Did you mean 'typeof CoolDto'?
I'm getting it when trying to use CoolDto e.g. in such context:
Copy code
type SomeCoolReactState = {
  coolDtoState: CoolDto | null,
}
the above happens when I import the class like this:
Copy code
import { com } from '../../sharedModel';
const { CoolDto } = com.example.myproject;
And when I try a regular
import
:
Copy code
import CoolDto = com.example.myproject.CoolDto;
then the TypeScript compiler complains with such message:
Copy code
`import =` is not supported by @babel/plugin-transform-typescript
Please consider using `import <moduleName> from '<moduleName>';` alongside Typescript's --allowSyntheticDefaultImports option.
From what I checked, it's not possible to use
import
when namespaces are used đŸ€”
d
Ahhh I see. You should use the
--allowSyntheticDefaultImports
option
Or add
"allowSyntheticDefaultImports": true
to your tsconfig.json file
And then just use the
import CoolDto = com.example.myproject.CoolDto;
p
I already have
"allowSyntheticDefaultImports": true,
in tsconfig.json
I'll try with the option
I think I need to prepare a minimal, buildable project out of this problem 😄 there might be some extra context I'm missing when describing the problem
d
I think it should work with that option, that's how I have it set up anyway. But yeah, maybe something's missing, or maybe it's not reading that config? đŸ€”
Btw here is a relevant issue in the Typescript repo https://github.com/Microsoft/TypeScript/issues/13135 it might be worth adding a Kotlin use case to the issue
p
I know the config is read because if I change the flag to
false
, the code on the main branch doesn't build. Anyway, thanks a lot for your help so far! will revisit this topic next week.
👍 1
as promised, I prepared a simple project where the issue reproduces: https://github.com/krzema12/kotlin-sharing-model-with-typescript See the README to learn how to use it. In short, just run
yarn build
and you'll see the issue I'm facing. I'd be really grateful if you could take a look @Derek Ellis
d
Ahhhh I see now. I guess create-react-app uses
@babel/plugin-transform-typescript
which doesn't like the
import =
syntax. My project is set up using webpack and we don't use babel which I guess is how I've avoided this issue
I can give it a try later, but the babel docs list a workaround for the problem: https://babeljs.io/docs/en/babel-plugin-transform-typescript.html#caveats
The
babel-plugin-replace-ts-export-assignment
plugin
p
isn't the plugin about transforming
export =
? the problematic part is
import =
(I tried the plugin just in case - doesn't work 😄 )
d
Oh wait I guess I read that wrong lol
👍 1
That's pretty annoying honestly. It'd be nice if they declared the namespaces as a module path instead that way you could do
import { Cat } from "com/github/krzema12/api"
I guess the only way to use the typescript definitions as-is is to set up a build that uses
tsc
itself instead of babel
I wonder if there's a youtrack issue for this
p
Yeah, I thought about the same (module path). Maybe I'll use this workaround locally, I'll simply modify the file using build logic + will report it on Youtrack as a bug (something that holds me back from using it)
d
I think it'd still be worth noting this particular use case, since I think it could be quite common
👍 1
p
Thanks for your help!