Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: scoped platform API types #45

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

Open
NathanWalker wants to merge 3 commits into NativeScript:main
base: main
Choose a base branch
Loading
from NathanWalker:feat/scoped-platform-types

Conversation

@NathanWalker
Copy link

@NathanWalker NathanWalker commented Dec 26, 2022

See RFC for details. In summary:

Historically NativeScript has always provided platform API types on the global scope, for example:

// available anywhere you type
NSString. 
java.

Progressive ideas around handling platform API types have emerged in 2022 among TSC discussions.

Here are the biggest three options in consideration.

A. import from runtime packages

import { NSString } from '@nativescript/ios'
import { java } from '@nativescript/android'

The types could ship with the runtimes themselves either directly or via proxy to @nativescript/types.

B. import from existing types packages explicitly

import { NSString } from '@nativescript/types-ios'
import { java } from '@nativescript/types-android'

B. import specifiers

See how Node is handling here, eg ... from 'node:fs'

Prior Art: nodejs/node#43413

// esm:
import { NSString } from 'native:Foundation';
// commonjs:
const NSString = require('native:Foundation').NSString;

For third party vendors:

// Objective C/Swift
import { LOTAnimationView } from 'native:Lottie';
// Java/Kotlin
import { LottieAnimationView } from 'native:com.airbnb.lottie';

NathanWalker reacted with thumbs up emoji
Copy link
Member

Thanks for bringing this up as an RFC! There are many related topics that this can start a conversation around.

I'm not entirely sold on such a big shift (with either option). I feel like it's a big mental shift to require thinking about imports, plus all content that includes example code would technically become incorrect even more so than it currently is (lot's of tns-core-modules/* out there in the wild).

The other side to this is more on the technical level. Types currently reflect how the runtimes work, moving types into deeper imports would require changes to both the build tooling and the runtimes to support, since this wouldn't purely be a typing/TypeScript change. Supporting both current and the proposed syntax at the same time would increase the maintenance overhead of the runtimes.

However, I think our types could be optimized, especially on android. Pairing them down to less, and perhaps more concise/better TypeScript declarations would be a huge step forward. For example, we could start dropping all but latest API versions from the types package (iOS already does this). This would greatly reduce the overhead of all these dts files in editors. Another point of optimization would be to correctly group namespaces/modules instead of re-declaring them multiple times (on the dts-generator side).

Currently, the dts-generator outputs in this format:

declare module android {
 export module R { /* ... */ }
 /* ... */
}
declare module android {
 export module accessibilityservice { /* ... */ }
 /* ... */
}
declare module android {
 // ...
}
declare module android {
 // ...
}

Notice how we have multiple declare module android { blocks - these could all be grouped together.


On Android/java code is organized into packages, however symbols can be "exported" at any level and in those cases you would be required to import from different levels individually.

import { LottieAnimationView } from 'native:com.airbnb.lottie';
import { LottieCallback } from 'native:com.airbnb.lottie.callback';

Not sure if this would be a "con", just thought I'd mention.


Finally, a few remarks/nits:

It's long been debated and even attacked as to whether platform API types should be on the global scope.

I haven't really noticed this being debated, though it does occasionally surprise people that they don't need to import anything to access android. for example.

This would improve developer experience and help the TSC optimize various compiler behaviors.

I think it would be useful to elaborate on how this would affect dx and what optimizations would be possible on the compiler level (I presume easier metadata filtering for example).

is it more clear or less clear

At first it feels less clear to me, however I'm open to try a minimal POC version (purely based on types, not necessarily functional) in my editor to feel it out.

mukaschultze, NathanWalker, and jcassidyav reacted with thumbs up emoji

Copy link

ammarahm-ed commented Mar 1, 2023
edited
Loading

Has anyone thought about re-exporting globals as scoped imports? That would not require any changes in the runtime or build tooling plus allow us to migrate from global to scoped imports in a step by step process.

For example a module "ns-string"

export const NSString = globalThis.NSString;
declare module "ns-string" {
 NSString: globalThis.NSString
}

We can customize the metadata generators to generate these single module files for each api with the above format which can be imported in code editors.

And you can use it as

import { NSString } from "ns-string";
const val = NSString.alloc().init();

This would simplify metadata filtering a lot probably. And i think it's simple to do.

vallemar reacted with thumbs up emoji

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /