Skip to content
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

Move interfaces for interpreter types to OSS #37753

Merged
merged 19 commits into from
Jun 10, 2019

Conversation

lukeelmers
Copy link
Member

@lukeelmers lukeelmers commented May 31, 2019

Currently Canvas maintains interfaces for the various types used in the Interpreter. This PR does the following:

  1. Copies those types over to the OSS Interpreter and colocates them with the type specs so they can be imported by folks developing custom interpreter functions. (The ExpressionFunction generic which was added in Expression typings: Canvas to OSS #37438 expects users to provide Context and Return types, so this way users will be able to import some of the commonly used types directly from the interpreter and provide those to ExpressionFunction).
  2. Introduces an ExpressionTypeDef generic that defines the interface for interpreter type specs.
  3. Converts all Interpreter Types to TypeScript.

I have specifically avoided removing the duplicate types from Canvas in this PR to keep things small. In a subsequent PR we can remove those duplicates and update the Canvas imports so everything is sharing the same interfaces.

Note to reviewers: There was some weirdness when Github diffed these changes... It shows completely separate files as being moved & I have no idea why. It's probably easiest to review this commit-by-commit instead of looking at the overall diff.

type: typeof name;
spec: any;
css: string;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this interface because it didn't exist yet. Is this correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like it's getting moved up in #37619 anyway -- that PR is likely to merge sooner, so i'll just wait for it to land and rebase this PR.

@lukeelmers lukeelmers added :AppArch Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) review v7.3.0 v8.0.0 labels May 31, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-canvas

@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@clintandrewhall clintandrewhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comments... @w33ble, your input on intention would be helpful here, as well.

paginate: true,
perPage: 10,
showHeader: true,
},
};
},
pointseries: datatable => {
pointseries: (dtable): PointSeries => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is there a reason dtable is not typed inline? I'm sure it's coming from somewhere, but the fact I can't find it easily might mean an inline type that matches would be helpful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clintandrewhall Yep, it's because this is already handled in the ExpressionType generic. We know that any function on a key in to is always going to cast the current type (which is passed into the generic) to something else. And we know that any function on a key in from is always going to return the current type (which is passed into the generic).

So TS should enforce here that the first arg to any of these to functions matches the Datatable interface

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But to your point, if that feels too "magical" it wouldn't hurt to explicitly say dtable: Datatable, it just isn't necessary as the generic already wires it up for you


const name = 'image';

export const image = (): ExpressionType<typeof name, undefined> => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: do you mean undefined or do you mean any? Because undefined would imply that no one should have any context at all passed in, whereas any would mean the context is inconsequential... I think this more style than anything, though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't thinking about style here so much as what would happen if we were to go back and add a proper Image interface in the future... If we keep this as undefined, then TS will blow up as soon as you start writing other methods that rely on this being anything other than undefined.

Whereas if we put any, it would be easier to forget to come back and put the proper parameter in place later, giving us a false sense of type safety.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm realizing now this doesn't need to be undefined at all, since we have a type for Image already in the Canvas image() function. Will update that here too.

/**
* Allowed column names in a PointSeries
*/
export type PointSeriesColumnName = 'x' | 'y' | 'color' | 'size' | 'text';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would convert this to an enum.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied this straight from Canvas but I agree an enum might be useful here.

I'm going to leave as-is for now because I don't want the implementations between Canvas & this PR to diverge (since I'm not deleting any Canvas code here). To keep PRs clean, I'd prefer to wait until Canvas has flipped over to using all of these types, and then change it over at that point.

type: typeof name;
spec: any;
css: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukeelmers lukeelmers force-pushed the feat/interpreter-types-oss branch from 817399e to 52b752c Compare June 10, 2019 16:52
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@clintandrewhall clintandrewhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot to follow up on, but LGTM.

* A generic type which represents a custom Expression Type Definition that's
* registered to the Interpreter.
*/
export interface ExpressionTypeDef<Name extends string, Type, SerializedType = undefined> {
Copy link
Contributor

@clintandrewhall clintandrewhall Jun 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this is personal style, but I got confused by this name. Seeing it in other files had me thinking it meant type as in Typescript and def was redundant. Naming is the hardest thing, so it's up to you.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this is a tough one; I thought the same thing about potential for confusion when using "def". I had changed it because @w33ble pointed out that elsewhere in Canvas, we refer to these as the Type "Definitions"; I'm happy to revert though, as I don't feel strongly one way or the other.

Copy link
Contributor

@clintandrewhall clintandrewhall Jun 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm torn, honestly. Some other options that might be less confusing:

  • Expression (isn't that really what this is?)
  • ExpressionTypeDefinition
  • ExpressionTD (ugh)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expression (isn't that really what this is?)

No, this is a definition for the various data types that the expression handles. And there's a distinction between a type's definition (the object this interface is defining) and it's instance (what is provided by the TypeRegistry).

I mentioned preferring adding something extra to the ExpressionType name, since there will also be an instance of ExpressionType that is created using this definition.

Copy link
Contributor

@w33ble w33ble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I flipped through this, seems fine. But I'm a TS newb so ┐( ̄ヮ ̄)┌

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@lukeelmers lukeelmers merged commit c4d851c into elastic:master Jun 10, 2019
@lukeelmers lukeelmers deleted the feat/interpreter-types-oss branch June 10, 2019 22:28
lukeelmers added a commit to lukeelmers/kibana that referenced this pull request Jun 10, 2019
@lukeelmers lukeelmers added release_note:skip Skip the PR/issue when compiling release notes and removed review labels Jul 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) release_note:skip Skip the PR/issue when compiling release notes Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas v7.3.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants