Does anyone know why I can’t import the interfaces...
# javascript
j
Does anyone know why I can’t import the interfaces from the .d.ts file built from the IR backend?
In my .d.ts file, I have something that looks like this:
Copy code
export namespace com.company.package.foo {
    interface MyInterface {
        foo(): void;
    }

    class SomeClass {
    // ...
    }
}
I can import classes and functions fine, but can’t import the interface
Copy code
import Package from 'package';

Package.com.company.package.foo.SomeClass // good
Package.com.company.package.foo.MyInterface // bad
Obviously, one key difference here is that the interface is a type and the class and functions are values
That doesn’t really explain to me why types aren’t being exported though. None of these worked as solutions.
Copy code
import * as Package from 'package'
Copy code
import type Package from 'package'
Copy code
// importPackage.ts
import Package from 'package';

export const Foo = Package.com.company.package.foo;

// Another file...

import { Foo } from './importPackage'
const x: Foo.MyInterface; // not there!
b
What error do you get and where?
Have you tried compiling your last sample with tsc?
How do you have your project setup? Can you share a repo?
Have you tried
Copy code
import Package from 'package';
let x: Package.com.company.package.MyInterface
j
No error, just can’t find the interface
This is in my IDE (VSCode)
b
Then must be an ide misconfiguration
j
We’re using the Babel typescript transform via Next.js, not tsc
Hmm, I’m not sure
This was an error in my vim setup too
b
Try packing it with npm-publish plugin and installing tarball to your next.js project
j
I’m currently copying across the build output from using npm-publish
Then putting that in the root of my directory and importing
So not going via NPM or GitHub packages
b
Upgrade it to 1.0.1 and use pack task to get tarballs
j
Do you think that’s likely to make a difference?
b
Then do npm install <path to tarball>
Copying is often unreliable with npm :/
j
Cool, I’ll give that a go first thing tomorrow morning
Thanks for your help again!
b
Np. Curious how it will end up myself
Been playing around with this myself a bit. Here's a working sample for you. Oddly enough, TS declarations generated for normal kotlin interfaces does not match backing JS, because declarations export interface properties as fields, where compiled js has them as getters (TS:
X.name
, JS:
X.get_name()
). This works fine if you mark your interfaces as
external
j
Thanks!
b
Just pushed few more samples to indicate various cases where internal/external interfaces do and do not work.
j
I think I’m running into one…
b
Easiest solution (provided your use case allows it) is to mark all exported interfaces as external
j
I’m getting a build error in that case
b
And then have
interface KMyInterface: MyInterface
j
Modifier 'external' is not applicable to 'class'
b
And only use KMyInterface in your kotlin code
j
Copy code
@JsExport
external interface SessionPresenting {
    fun presentLoading()
    fun presentCard(card: Card, sessionProgress: SessionProgress)
    fun presentSummary(bonusPoints: Int)
}
b
Ah, but classes are fine
Wait, is Card a class?
j
No, an interface
b
In that case you'll need to split your interfaces. Have external interface containing only your properties and extended non-external interface adding in the methods
or just don;t use properties in interfaces
j
SessionProgress is a data class, however
b
i.e. instead of
val name:String
use
fun getName(): String
Functions should work fine in non-external interfaces
j
Been playing around with this myself a bit. Here’s a working sample for you. Oddly enough, TS declarations generated for normal kotlin interfaces does not match backing JS, because declarations export interface properties as fields, where compiled js has them as getters (TS: 
X.name
, JS: 
X.get_name()
). This works fine if you mark your interfaces as 
external
I’m confused by this message. Do you mean to say Kotlin interfaces get exported as values, not types at some point?
If so, it sounds like Kotlin interfaces are quite different to TS ones (TS interfaces only exist as types)
b
Kotlin's too
It's just a bug in declaration generation where generated TS declaration is field and backing js code is property getter
j
So, I need to refactor to avoid all properties on interfaces and replace them with getters?
b
Correct
Just pushed another commit outlining this behavoiur
j
🙃
Thanks 🙂
Annoying the compiler isn’t quite there yet…
b
Have a look at BuggedPerson & sayFormalBuggedHello
when you run that ts file the output is as follows
Copy code
Hi
Hello from Martynas
Hello from Yo Mama
Hello from Should Still Work
Safe hello from Safe Word "fun"
CRASH, stack trace & etc... due to 
    var str = '' + 'Hello from ' + person._get_name__0() + ' ' + person._get_sureName__0();
                                          ^
TypeError: person._get_name__0 is not a function
j
Yuck
b
Also, keep in mind that TS declarations are experimental and IR comiler is still in alpha. So things like these are expected 🙂
j
Yes, I suppose I should have known better. It’s just that we’re manually typing everything atm and it’s a pain and difficult to accurately update changes
b
I'd choose avoiding props in interfaces over manually typing everything
j
So, to summarise the issues here (please correct me if I’m wrong): 1. There is a bug in the compiler where values implementing interfaces using
val
properties have those vals accessed using getters in the JS, but are exported as straightforward interfaces with properties in the
.d.ts
file. 2. We can work around this by marking the class as external (e.g. here: https://gitlab.com/lt.petuska/npm-publish/-/blob/develop/sandbox/mpp/src/jsIRMain/kotlin/test/sandbox/index.kt#L22) 3. But external doesn’t work when functions on an interface take a class as one of the parameters 4. So a refactor to use getter functions instead of
val
is needed
5. Hopefully, this behaviour should disappear soon when the bug is patched
b
Mostly correct except that this applies for
var
too. Raised a YT to track.
youtrack 1
🙏 1
K 1
a
b
Can you add your findings to that YT I've raised?
👍 1