Kitware / vtk-js

Visualization Toolkit for the Web
https://kitware.github.io/vtk-js/
BSD 3-Clause "New" or "Revised" License
1.23k stars 371 forks source link

Typescript type definitions #466

Closed masonlr closed 3 years ago

masonlr commented 6 years ago

Are typescript type definitions planned for vtk.js? (as per available packages for three.js, for example https://www.npmjs.com/package/@types/three)

jourdain commented 6 years ago

I guess not yet but definitely interesting. I would be interested to learn more about the tools you use that make those type declaration most useful. Thanks!

masonlr commented 6 years ago

Mainly for compatibility with angular. We are building web based science gateway apps for education, and frameworks such Vue.js and angular are trending towards typescript use.

jourdain commented 6 years ago

I guess that will require some more investigation on our end.

weidonglian commented 6 years ago

I noticed that Kitware has massive web projects using Javascript. No offense and just out of curiosity, what is the big consideration not to use Typescript in Kitware? Typescript seems to be more proper for larger projects like vtkjs, better IDE, Testing, Productivity support.

Sure, probably you guys in Kitware are more familiar with and get used to Javascript or Typescript is not the standard.

jourdain commented 6 years ago

Typescript was at its beginning when we started vtk.js and ES6 was already widely used on other projects. It is true that some parameters could get some benefit from types. But in other cases, we rather have no specific types. Also I don't know if that matters (since I have no experience with TypeScript), but none of the vtk objects are classes and we use a factory approach to generate functions as closures. In other words, the vtk.js infrastructure allow us to generate and write less code thanks to the type-less definition...

weidonglian commented 6 years ago

Thanks for your reply.

ThisNameNotUsed commented 5 years ago

If anyone has a free moment to expand on this... I have been tasked with moving a medium-large C++ VTK project to webtech. I was hoping to use Angular and VTK.js. Should I abandon Angular now or maybe explore the possibility of switching to three.js for the webtech version? I am pretty set on using Angular and I see that three.js now supports types in-house.

jourdain commented 5 years ago

vtk.js should work just fine with angular. Is TypeScript preventing you of using plain JavaScript? The main issue with vtk.js is that the methods get built dynamically. There might be an option to create some type information on the side, but I did not explore that path yet.

yasushi-saito commented 4 years ago

Is there any activity on this issue? We can start adding definitions. Or even better, we can start incrementally converting the existing js files to ts. I can help if you think it's a good idea.

jourdain commented 4 years ago

Hi @yasushi-saito, I would love to start seeing some progress on that topic but I'm not sure how to properly handle that with out macro approach. I was thinking of using side files that could map to actual API. But since I'm not well versed in ts, it would be great if you could provide some possible example via small PR and then we can discuss what would make more sense.

What do you think?

daniel-karl commented 4 years ago

upvote

kmannislands commented 4 years ago

@jourdain what you've described there:

using side files that could map to actual API

This is exactly what .d.ts (type declaration) files are intended for!

An example, when you compile ts to a library target, the compiler spits out js files that have the actual runtime logic and .d.ts that type your API interface. These typings are technically useless at runtime but are there for other ts projects to consume.

Back to vtk, I'm not across what code is automatically generated vs manually created and maintained but you can certainly manually create type declarations in the form of .d.ts files. It sounds like the way to go for vtk, at least initially. If these .d.ts files become difficult to maintain, then it may be worth switching from babel to tsc as your compiler/transpiler. This can be done incrementally (as in most/all files are js and get typed as they're touched) and is worth weighing as an option.

I hope this is context is useful!

jourdain commented 4 years ago

Thanks @kmannislands I was aware at the high level concepts and possibilities but where I struggle is how to go by doing it with creating by hand those .d.ts files so they could be useful for an IDE in the context of vtk.js. So I was asking for 1 example of an existing class to see how it should/could be done and figure out if we could automate some of it. For example vtkDataArray or vtkCellArray that inherit from vtkDataArray.

bingliang-zh commented 4 years ago

@jourdain , just for demonstration. It is important to remove any 'any' if possible, but that need more information in other files, so I just ignored them.

// Handwritten typescript description file for CellArray.js in vtk.js by bingliang
// Warning: not tested or verified, only for demonstration use.
export const STATIC: {
    extractCellSizes: (cellArray: Number[]) => Number[];
    getNumberOfCells: (cellArray: Number[]) => Number;
};
export declare function extend(publicAPI: any, model: any, initialValues?: {}): void;
export const newInstance: any;

const CellArray = {
    newInstance,
    extend,
    ...STATIC
};
export default CellArray;
bingliang-zh commented 4 years ago

As for automation, vscode has some kind of 'hint' if the function/value name is hovered. Copy/paste manually and then infer as much 'any' as possible.

jourdain commented 4 years ago

Thanks @bingliang-zh is it a definition that you put inside a .d.ts? Next to the JS side and were we only expose the methods profile? If so this is great...

Is it possible to provide some documentation along those methods definition so VSCode could provide more hints?

How can also define some vtkObject, vtkAlgorithm, ... interface?

jourdain commented 4 years ago

Typically a newInstance() function would return a mix of vtkObject > vtkAlgoritm > CustomFilterAPI.

bingliang-zh commented 4 years ago

Thanks @bingliang-zh is it a definition that you put inside a .d.ts? Next to the JS side and were we only expose the methods profile? If so this is great...

Yes and yes. Btw bundle these d.ts files in release need some tweaks in webpack/etc.

Is it possible to provide some documentation along those methods definition so VSCode could provide more hints?

VSCode don't work this way by default. Maybe some plugins? I don't know if that's possible or not.

bingliang-zh commented 4 years ago

How can also define some vtkObject, vtkAlgorithm, ... interface?

Algorithms are fairly simple if they are pure functions. Objects need some work to list every property names. If property names are uncertain (such as specified in runtime), my method is leave 'any' there.

Interface is just like Object but much easier to use.

export interface MyInterface extends BaseInterface {
  foo: Foo; // must have
  bar?: Bar; // may not have
  functionA?: (payload: Payload) => void;
}

Typically a newInstance() function would return a mix of vtkObject > vtkAlgoritm > CustomFilterAPI.

Then it could be something like this.

// if vtkObject is the base class
export const newInstance: VtkObject;
// if they are not inherited strictly
export const newInstance: VtkObject | VtkAlgoritm | CustomFilterAPI;
// if we know exactly what it is
export const newInstance: VtkAlgoritm1 | VtkAlgoritm3;

// reuse type bundles
type K = VtkObject | VtkAlgoritm | CustomFilterAPI;
export const newInstance: K;
export const newInstance2: K;
jourdain commented 4 years ago

I'm starting to work through the macro and I have a question for VtkPipelineConnection which is a function that as a nested filter field?

Here is what I have but I'm not sure it is valid.

interface VtkOutputPort {
  filter: VtkAlgorithm;
}

// I'm not sure if that is correct
type VtkPipelineConnection = () => any | VtkOutputPort;

interface VtkAlgorithm {
  setInputData: (dataset: any, port: number = 0) => void;
  getInputData: (port: number = 0) => any;
  setInputConnection: (outputPort: VtkPipelineConnection, port: number = 0) => void;
  getInputConnection: (port: number = 0) => VtkPipelineConnection;
  addInputConnection: (outputPort: VtkPipelineConnection) => void;
  addInputData: (dataset: any) => void;
  getOutputData: (port: number = 0) => any;
  shouldUpdate: () => boolean;
  getOutputPort: (port: number = 0) => VtkPipelineConnection;
  update: () => void;
  getNumberOfInputPorts: () => number;
  getNumberOfOutputPorts: () => number;
  getInputArrayToProcess: (inputPort: number) => VtkDataArray;
  setInputArrayToProcess: (inputPort: number, arrayName: string, fieldAssociation: string, attributeType: string = 'Scalars'): void;
}

Any suggestion will be great.

alesgenova commented 4 years ago

This is really exciting to see, I would also love typescript integration in vtkjs!

FYI @jourdain , @cjh1 and I have been using typescript in pretty much all the kitware projects we have worked on over the past year and a half if you need more hands on this.

jourdain commented 4 years ago

Thanks @alesgenova, I'm trying to get a feel of it. We won't be able to write in TypeScript natively as many of the code get generated (runtime closure for method generation), but if we can provide type feedback and API documentation through that. That will be great. I'm just going to do a couple of core components and then it might be indeed good to see how useful it is for a user and what I might be missing to really make it available to the IDE. Because right now, even after writing the macro.d.ts, I still don't get those definition picked up in VSCode when writing something that use a macro function...

alesgenova commented 4 years ago

Don't have much experience on writing manual typings, so I'm not sure why VSCode isn't picking it up, but have you included an entrypoint for the types in the package.json?

{
  ...
  "types": "./dist/index.d.ts" // Or wherever your type files will be put
}

An example of a project written in JS that bundles manual typings is redux-saga: https://github.com/redux-saga/redux-saga/tree/master/packages/redux-saga

Alternatively, you can find thousands of 3rd party typings written for JS libraries under the DefinitelyType organization: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types

jourdain commented 4 years ago

I did a first quick pass here https://github.com/Kitware/vtk-js/pull/1436 Can someone validate that it provides some value and that it actually do something in their IDE.

Also let me know what I might be missing to make that part work. Thx!

ellvtr commented 3 years ago

Hi, I'd love for VTK.js do support TypeScript. Perhaps I can contribute?

I am addicted to TypeScript and I work on a daily basis as frontend developer on a large complex engineering application using VTK.js. I took over the 3 year old code base in May - now 10 months later, I struggle more than ever to debug or expand on VTK functionality in the application. Countless hours and days, I've trawled through the documentation and source code for VTK.js but it remains a black box to me, thus prevents me and the team from making improvements to the 3D part of the application.

TypeScript not only prevents runtime errors abut also serves as documentation and provides intellisense in the editor (VS code in my case).

TypeScript gives:

ellvtr commented 3 years ago

Hi @jourdain, I will check if those description files made a difference and get back to you within a few weeks.

jourdain commented 3 years ago

Hi @ellvtr,

It will be awesome if you could help. And you don't have to argue why TS is important. We are all well aware but we just struggle to find the time to push that forward. I also believe and hope that I can use TS to provide a better API documentation (hence my first push here). Ideally, I want to use the type definitions files to generate markdown for the website but that part can come later.

I think our bigger struggle is how we should distribute those types so they became available and useful for the community. Any guidance or even first step with a partial solution that can evolve would be a huge step forward.

Also, I believe that we can only do it via definition files on the side as a lot of methods get generated with the type flexibility in mind while they should become specialized once used inside a class definition. Also having those definition files, we can extend them with usage and else.

Anyhow, ideally if you could help us get started that will invaluable.

And please let us know, what we can do to help you, help us. ;-)

Thanks and looking forward for your feedback!

Seb

FezVrasta commented 3 years ago

Adding my vote, it'd be nice if Flow was supported too. Take a look at how https://github.com/popperjs/popper-core manages to provide both type systems with minimal effort.

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 17.0.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 17.1.2 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 17.2.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 17.2.6 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 17.4.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: