Skip to content

Commit

Permalink
Support TypeScript 3.9 and 4.x
Browse files Browse the repository at this point in the history
To make tabris TypeScript 4.x-compliant some changes are needed in the
type declarations:

* The "properties" parameter of "set" overrides need to assignable to
their respective type in the super class. This is not the case if
properties are explicitly excluded via "Omit" but included in the super
class. Various other mechanism to exclude read-only properties either
don't work with specific TypeScript versions or cause breaking changes.
Therefore these overrides are removed. Regrettably this means that it is
now possible (at compile-time) to use "set" to set read-only values,
though they are still excluded from the constructors.

* The same issue applies to jsxAttributes, but here a workaround is
possible: Instead of omitting attribute they are joined with "never".
This means they are still auto-suggested by the IDE, but actually using
them causes a compile error. This workaround is possible because it is
assumed that the JSXAttribues<T> type is (unlike Properties<T>) is never
used outside of class declarations.

* NativeObject property "_nativeType" must be declared with an explicit
getter to able to override it with one, as is the established way to
define it in code. To allow this the declarations generator and api json
schema need to be extended. This includes a minor unrelated fix in
api-schema.d.ts

* d.ts files may can longer be linted by eslint. The reason for this is
unclear.

Change-Id: I58fbceab2df94f03ebe658173965d5fdc7b60751
  • Loading branch information
tbuschto committed Sep 30, 2020
1 parent 38a5517 commit 8045159
Show file tree
Hide file tree
Showing 22 changed files with 41 additions and 198 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tools/*.d.ts
*.d.ts
test/typescript/*
build
node_modules
Expand Down
12 changes: 0 additions & 12 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -412,18 +412,6 @@
}
]
}
},
{
"files": [
"*.d.ts"
],
"rules": {
"max-len": "off",
"no-redeclare": "off",
"no-var": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-member-accessibility": "off"
}
}
]
}
Expand Down
24 changes: 1 addition & 23 deletions doc/api/AlertDialog.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,31 +51,9 @@
"const": true,
"readonly": true,
"ts_only": true,
"type": "JSXAttributes<Omit<this, 'textInputs'>> & {children?: Flatten<string|TextInput>}"
"type": "JSXAttributes<this> & {children?: Flatten<string|TextInput>, textInputs?: never}"
}
},
"methods": {
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'textInputs'>>"
}
],
"description": "Sets all key-value pairs in the properties object.",
"returns": "this"
}
]
},
"events": {
"close": {
"description": "Fired when the dialog was closed for any reason.",
Expand Down
2 changes: 1 addition & 1 deletion doc/api/CollectionView.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'firstVisibleIndex' | 'lastVisibleIndex'>> & Partial<Pick<this, 'cellHeight' | 'cellType' | 'createCell'>>"
"type": "Properties<T> & Partial<Pick<this, 'cellHeight' | 'cellType' | 'createCell'>>"
}
],
"description": "Sets all key-value pairs in the properties object as widget properties.\n\n**Important TypeScript note:** When called on `this` you may need to specify your custom type like this: `this.set<MyComponent>({propA: valueA});`",
Expand Down
3 changes: 2 additions & 1 deletion doc/api/NativeObject.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"_nativeType": {
"readonly": true,
"protected": true,
"type": "string"
"type": "string",
"separateAccessors": true
},
"_isDisposed": {
"protected": true,
Expand Down
22 changes: 0 additions & 22 deletions doc/api/NavigationBar.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,6 @@
}
}
},
"methods": {
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'height'>>"
}
],
"description": "Sets all key-value pairs in the properties object.",
"returns": "this"
}
]
},
"links": [
{
"title": "Demonstrating various properties of the `NavigationBar`",
Expand Down
24 changes: 1 addition & 23 deletions doc/api/Popover.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"const": true,
"readonly": true,
"ts_only": true,
"type": "JSXAttributes<Omit<this, 'contentView'>> & {children?: JSXChildren<Widget>}"
"type": "JSXAttributes<this> & {children?: JSXChildren<Widget>, contentView?: never}"
},
"contentView": {
"const": true,
Expand All @@ -50,28 +50,6 @@
}
}
},
"methods": {
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'contentView'>>"
}
],
"description": "Sets all key-value pairs in the properties object as Popover properties.",
"returns": "this"
}
]
},
"statics": {
"methods": {
"open": [
Expand Down
22 changes: 0 additions & 22 deletions doc/api/StatusBar.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,6 @@
"description": "Background color of the status bar. Should be used in conjunction with the `theme` property to keep the status bar icons legible."
}
},
"methods": {
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'height'>>"
}
],
"description": "Sets all key-value pairs in the properties object.",
"returns": "this"
}
]
},
"events": {
"tap": {
"description": "Fired when status bar is tapped.",
Expand Down
4 changes: 2 additions & 2 deletions doc/api/TabFolder.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"selection": {
"description": "The `Tap` selected by the user.",
"type": "Tab",
"ts_type": "Target extends TabFolder ? Target['selection'] : Tab"
"ts_type": "Target extends TabFolder<any> ? Target['selection'] : Tab"
}
}
},
Expand All @@ -105,7 +105,7 @@
"selection": {
"description": "The current value of the `selection` property.",
"type": "Tab",
"ts_type": "Target extends TabFolder ? Target['selection'] : Tab"
"ts_type": "Target extends TabFolder<any> ? Target['selection'] : Tab"
},
"offset": {
"description": "Number of pixels the current tab has scrolled horizontally.",
Expand Down
22 changes: 1 addition & 21 deletions doc/api/Video.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,7 @@
}
],
"description": "Starts playing the video, *[state](#state)* changes to `play`. Has no effect unless the current state is either `pause` or `ready`."
},
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'speed' | 'position' | 'duration' | 'state'>>"
}
],
"description": "Sets all key-value pairs in the properties object as widget properties.\n\n**Important TypeScript note:** When called on `this` you may need to specify your custom type like this: `this.set<MyComponent>({propA: valueA});`",
"returns": "this"
}
]
}
},
"links": [
{
Expand Down
20 changes: 0 additions & 20 deletions doc/api/WebView.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,6 @@
"parameters": [],
"description": "Navigate the `WebView` to the next page if possible."
}
],
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'canGoBack' | 'canGoForward'>>"
}
],
"description": "Sets all key-value pairs in the properties object as widget properties.\n\n**Important TypeScript note:** When called on `this` you may need to specify your custom type like this: `this.set<MyComponent>({propA: valueA});`",
"returns": "this"
}
]
},
"links": [
Expand Down
22 changes: 1 addition & 21 deletions doc/api/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,27 +247,7 @@
}
],
"description": "Allows to register a font to use throughout the app. Once a font is registered its alias can be used to apply the font where ever a font can be configured, e.g. in `TextView` or `GraphicalContext`. Tabris.js supports TrueType fonts (*.ttf) and OpenType fonts (*.otf)."
},
"set": [
{
"ts_only": true,
"generics": [
{
"name": "T",
"extends": "NativeObject",
"default": "this"
}
],
"parameters": [
{
"name": "properties",
"type": "Properties<Omit<T, 'id' | 'debugBuild' | 'versionCode' | 'version'>>"
}
],
"description": "Sets all key-value pairs in the properties object.",
"returns": "this"
}
]
}
},
"links": [
{
Expand Down
2 changes: 1 addition & 1 deletion snippets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"tabris": "^3.6.1"
},
"devDependencies": {
"typescript": "3.8.x"
"typescript": "4.0.x"
},
"scripts": {
"build": "tsc -p .",
Expand Down
4 changes: 1 addition & 3 deletions test/typescript/NavigationBar.fail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ navigationBar.height = height;
navigationBar.onHeightChanged(function() {});

/*Expected
(4,
is not assignable to parameter of type
(5,
Cannot assign to 'height'
*/
*/
4 changes: 1 addition & 3 deletions test/typescript/StatusBar.fail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ statusBar.height = height;
statusBar.onHeightChanged(function() {});

/*Expected
(4,
is not assignable to parameter of type
(5,
Cannot assign to 'height'
*/
*/
4 changes: 0 additions & 4 deletions test/typescript/Widgets/CollectionView.fail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,10 @@ widget.lastVisibleIndex = lastVisibleIndex;

/*Expected
(6,
(7,
firstVisibleIndex
(8,
firstVisibleIndex
(11,
(12,
lastVisibleIndex
(13,
lastVisibleIndex
*/
10 changes: 1 addition & 9 deletions test/typescript/Widgets/Video.fail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,18 @@ widget.state = 'empty';

/*Expected
(6,
(7,
speed
(8,
speed
(11,
(12,
position
(13,
position
(16,
(17,
duration
(18,
duration
(21,
(22,
state
(23,
state
*/
*/
2 changes: 0 additions & 2 deletions test/typescript/Widgets/WebView.fail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ widget.canGoForward = canGoForward;

/*Expected
(6,
(7,
(8,
canGoBack
(11,
(12,
(13,
canGoForward
*/
2 changes: 1 addition & 1 deletion test/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"private": true,
"dependencies": {
"tabris": "../tabris",
"typescript": "3.8.x"
"typescript": "4.0.x"
}
}
6 changes: 5 additions & 1 deletion tools/api-schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export interface Api {
methods?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "(^[_\$]?[a-z]\w+$)|(^\[.*\]$|^\$$)".
* via the `patternProperty` "(^[_\$]?[A-Za-z]\w+$)|(^\[.*\]$|^\$$)".
*/
[k: string]: Method | Method[];
};
Expand Down Expand Up @@ -152,6 +152,10 @@ export interface Property {
* Exclude this property from documentation
*/
ts_only?: boolean;
/**
* Render declaration using separate getter and setter.
*/
separateAccessors?: boolean;
/**
* Mark property as protected
*/
Expand Down
Loading

0 comments on commit 8045159

Please sign in to comment.