-
Notifications
You must be signed in to change notification settings - Fork 831
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
Migrate to TypeScript #300
Comments
Not yet. Looking into Flow/TypeScript for the future. Probably a couple of major version out though. |
Would you take DTS PRs? |
@pspeter3 do you mean adding types? Not sure what DTS means. |
A single DTS file can provide type definitions for the entire project. It means you can continue to write in JavaScript while supporting TypeScript users. |
I would ❤️ to see typescript support! The options are
Option 3 would be the best :) (yes, I am biased because developing in typescript provides a much better developer experience compared to standard JS!) |
Plz consider reopen this issue. Evergreen's UI looks beautiful very much, the only reason blocks me using it is the missing of type definitions. |
This is heavy based on segmentio/ui-box so I would start with adding typescript there |
For the risk of being another +1, I just wanted to add in my support for this. I deal with react a few months each year, and seems the best UI frameworks right now for React are:
After comparing their modal dialog solutions, seems order of easiest to hardest are:
So it would be nice to see Evergreen be written in TypeScript, or for it to be published with TypeScript typings. |
UI Box seems similar to https://github.com/jsxstyle/jsxstyle which is typescript, so perhaps that can be a start |
Reopening as we explore paths towards TypeScript support. Some initial work has begun in ui-box which will be foundational for adding support in evergreen. 😊 |
Here's a PR with type definitions for ui-box: DefinitelyTyped/DefinitelyTyped#31750 I'm suspecting add type defs for evergreen will take a lot more work, so I was hoping we could take kind of a crowdsourced approach. How do y'all want to go about adding EG types? |
+1 here... |
An update for everyone following this – there are a few moving parts:
I wanted to outline some goals of these efforts so we can align, decouple risks in such a large effort, and distribute the load a bit. I see 2 primary goals for TypeScript in Evergreen: Provide type declarations for TypeScript consumersPeople who use Evergreen want to be able to do so with complete type-safety in their TypeScript projects. Reap the benefits of type-safety within Evergreen internalsPeople who contribute to Evergreen want to be able to do so with all of that amazing tooling around TypeScript. As a side-effect we can achieve the first goal (type declaration) with zero effort by outputting the declarations directly from the source. I think we can decouple these two goals. It will allow us to immediately ship type declarations while we incrementally migrate to TypeScript within the package. As @paustint aptly said, we can do this by providing a declaration file ( I prefer this approach because we can start compiling with TypeScript using our existing Babel setup immediately. Thoughts? |
More updates:
|
Is there a TODO list to see what needs working on/documenting what's been done? |
@robphoenix No! This is something we could use help spec'ing out. We are a bit blocked because spread props straight up don't work with TypeScript so anything wrapped in See Off the top of my head here's what we've done:
I guess that leaves:
|
Grand, thanks for the list @mshwery, I'll have a look at what's been done so far and see if I can help out with some of those components.
I've only used TS on it's own or with Angular before, just starting to use it with React, so I don't know much about this, I'll read up on it though, thanks for the links.
Would you mind expanding on this? Do you mean using the |
@robphoenix yes I'm talking about
The drawback is that you must use I'm not super opinionated about whether we introduce a breaking change (you cant use refs directly on evergreen components!) or not, but I generally prefer to minimize breaking changes even with major version bumps. Does that explanation help? |
@mshwery That explanation helps a lot, thanks for taking the time. |
Have you looked into |
@kingdaro to be honest, no sadly, I haven't spent much time looking into how those would work or how they would be different for consumers who today use |
@mshwery Well, these basically bring all of the // Do this if you want to directly use an element as a ref
function Input(props: InputProps, ref: React.Ref<HTMLInputElement>) {
return <input {...props} ref={ref} />
} // Use uIH if you want to support the old class way of methods on the ref
// This route requires making a custom ref type
export type InputRef = {
focus: () => void
inputElement: HTMLInputElement
}
function Input(props: InputProps, ref: React.Ref<InputRef>) {
const inputRef = useRef<HTMLInputElement>(null)
useImperativeHandle(ref, () => ({
focus() {
if (inputRef.current) inputRef.current.focus()
// do some special custom action here
},
// pass along the input element directly as an escape hatch to the user
inputElement: inputRef.current,
}), [])
return <input {...props} ref={inputRef} />
} function FormInUserLand() {
const inputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
if (inputRef.current) inputRef.current.focus()
}, [])
return <Input ref={inputRef} />
} Might've made a mistake in there, but hopefully you get the idea. The result for consumers is the same with class components, and backwards compatible |
so there are no TypeScript definitions available at all yet? |
Or you can create evergreen-ui/index.d.ts file. For starting you can use my partial file and extend missing definitions. index.d.ts
/* tslint:disable:interface-name max-classes-per-file no-empty-interface */
declare module 'evergreen-ui' {
import * as React from 'react';
type PositionTypes = 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
type IntentTypes = 'none' | 'success' | 'warning' | 'danger';
type IconNameTypes =
''
| 'loading'
| 'error'
| 'tick-circle'
| 'caret-down'
| 'cross'
| 'menu'
| 'list'
| 'more'
| 'properties'
| 'diagram-tree'
| 'database'
| 'join-table'
| 'function'
| 'person'
| 'import'
| 'predictive-analysis'
| 'refresh'
| 'export';
interface BoxBackground {
background?: string;
backgroundBlendMode?: string;
backgroundClip?: string;
backgroundColor?: string;
backgroundImage?: string;
backgroundOrigin?: string;
backgroundPosition?: string;
backgroundRepeat?: string;
backgroundSize?: string;
}
interface BoxBorderRadius {
borderBottomLeftRadius?: string | number;
borderBottomRightRadius?: string | number;
borderRadius?: string | number;
borderTopLeftRadius?: string | number;
borderTopRightRadius?: string | number;
}
interface BoxBorders {
border?: string;
borderBottom?: string;
borderBottomColor?: string;
borderBottomStyle?: string;
borderBottomWidth?: string | number;
borderColor?: string;
borderLeft?: string;
borderLeftColor?: string;
borderLeftStyle?: string;
borderLeftWidth?: string | number;
borderRight?: string;
borderRightColor?: string;
borderRightStyle?: string;
borderRightWidth?: string | number;
borderStyle?: string;
borderTop?: string;
borderTopColor?: string;
borderTopStyle?: string;
borderTopWidth?: string | number;
borderWidth?: string | number;
}
interface BoxShadow {
boxShadow?: string;
}
interface BoxDimensions {
height?: string | number;
maxHeight?: string | number;
maxWidth?: string | number;
minHeight?: string | number;
minWidth?: string | number;
width?: string | number;
}
interface BoxFlex {
alignContent?: string;
alignItems?: string;
alignSelf?: string;
flex?: string | number;
flexBasis?: string | number;
flexDirection?: string;
flexFlow?: string;
flexGrow?: string | number;
flexShrink?: string | number;
flexWrap?: string;
justifyContent?: string;
justifyItems?: string;
justifySelf?: string;
order?: string | number;
placeContent?: string;
placeItems?: string;
placeSelf?: string;
}
interface BoxGrid {
columnGap?: string | number;
gap?: string | number;
grid?: string;
gridArea?: string;
gridAutoColumns?: string | number;
gridAutoFlow?: string;
gridAutoRows?: string | number;
gridColumn?: string | number;
gridColumnEnd?: string | number;
gridColumnGap?: string | number;
gridColumnStart?: string | number;
gridGap?: string | number;
gridRow?: string | number;
gridRowEnd?: string | number;
gridRowGap?: string | number;
gridRowStart?: string | number;
gridTemplate?: string;
gridTemplateAreas?: string;
gridTemplateColumns?: string;
gridTemplateRows?: string;
rowGap?: string | number;
}
interface BoxInteraction {
cursor?: string;
pointerEvents?: string;
userSelect?: string;
visibility?: string;
}
interface BoxLayout {
boxSizing?: string;
clear?: string;
clearfix?: boolean;
display?: 'block'
| 'contents'
| 'flex'
| 'grid'
| 'inherit'
| 'initial'
| 'inline'
| 'inline-block'
| 'inline-flex'
| 'inline-grid'
| 'inline-table'
| 'list-item'
| 'none'
| 'table'
| 'table-caption'
| 'table-cell'
| 'table-columnr'
| 'table-column-group'
| 'table-header-group'
| 'table-footer-group'
| 'table-row'
| 'table-row-group'
| '';
float?: string;
zIndex?: number;
}
interface BoxList {
listStyle?: string;
listStyleType?: string;
listStyleImage?: string;
listStylePosition?: string;
}
interface BoxOpacity {
opacity?: string | number;
}
interface BoxOverflow {
overflow?: 'auto' | 'hidden' | 'inherit' | 'initial' | 'revert' | 'scroll' | 'unset' | 'visible';
overflowX?: 'auto' | 'hidden' | 'inherit' | 'initial' | 'revert' | 'scroll' | 'unset' | 'visible';
overflowY?: 'auto' | 'hidden' | 'inherit' | 'initial' | 'revert' | 'scroll' | 'unset' | 'visible';
}
interface BoxPosition {
bottom?: string | number;
left?: string | number;
position?: 'absolute' | 'fixed' | 'inherit' | 'initial' | 'relative' | 'revert' | 'static' | 'sticky' | 'unset';
right?: string | number;
top?: string | number;
}
interface BoxSpacing {
margin?: string | number;
marginBottom?: string | number;
marginLeft?: string | number;
marginRight?: string | number;
marginTop?: string | number;
marginX?: string | number;
marginY?: string | number;
padding?: string | number;
paddingBottom?: string | number;
paddingLeft?: string | number;
paddingRight?: string | number;
paddingTop?: string | number;
paddingX?: string | number;
paddingY?: string | number;
}
interface BoxText {
color?: string;
font?: string;
fontFamily?: string;
fontSize?: string | number;
fontStyle?: string;
fontVariant?: string;
fontWeight?: string | number;
letterSpacing?: string | number;
lineHeight?: string | number;
textAlign?: 'center' | 'end' | 'inherit' | 'justify' | 'left' | 'match-parent' | 'revert' | 'right' | 'start' | 'unset';
textDecoration?: string;
textOverflow?: string;
textShadow?: string;
textTransform?: string;
whiteSpace?: string;
wordBreak?: string;
wordWrap?: string;
}
interface BoxTransform {
transform?: string;
transformOrigin?: string;
}
interface BoxTransition {
transition?: string;
transitionDelay?: string;
transitionDuration?: string;
transitionProperty?: string;
transitionTimingFunction?: string;
}
interface UiBoxPropsType extends BoxBackground,
BoxBorderRadius,
BoxBorders,
BoxShadow,
BoxDimensions,
BoxFlex,
BoxGrid,
BoxInteraction,
BoxLayout,
BoxList,
BoxOpacity,
BoxOverflow,
BoxPosition,
BoxSpacing,
BoxText,
BoxTransform,
BoxTransition {
is?: React.ReactNode;
to?: string;
css?: object;
style?: object;
innerRef?: (ref: HTMLElement) => void;
onMouseDown?: (e: React.MouseEvent<HTMLInputElement>) => void;
onMouseUp?: (e: React.MouseEvent<HTMLInputElement>) => void;
}
export interface AlertProps extends BoxDimensions, BoxLayout, BoxPosition, BoxSpacing {
intent: IntentTypes;
title?: React.ReactNode;
hasTrim?: boolean;
hasIcon?: boolean;
isRemoveable?: boolean;
onRemove?: () => void;
appearance?: 'default' | 'card';
children?: React.ReactNode;
}
export class Alert extends React.PureComponent<AlertProps> {
}
// https://github.com/downshift-js/downshift
export interface AutocompleteProps {
title?: React.ReactNode;
items: any[];
itemToString?: (i: any) => string;
children: (props: {
toggle: () => void,
getRef: (ref: React.RefObject) => void,
isShown: NonNullable<PopoverProps['isShown']>,
getInputProps: () => {
onKeyDown: (e: React.ChangeEvent<any>) => void;
onChange: (e: React.ChangeEvent<any>) => void;
onBlur: (e: React.ChangeEvent<any>) => void;
},
openMenu: () => any,
inputValue: string,
},
) => React.ReactNode;
itemSize?: number;
position?: PositionTypes;
isFilterDisabled?: boolean;
popoverMinWidth?: number;
popoverMaxHeight?: number;
selectedItem?: any;
buttonProps?: buttonProps;
onChange: (selectedItem: any) => void;
}
export class Autocomplete extends React.PureComponent<AutocompleteProps> {
}
export interface AvatarProps {
src?: string;
size?: number;
name?: string;
hashValue?: string;
isSolid?: boolean;
color?: string;
getInitials?: (name: string) => string;
forceShowInitials?: boolean;
sizeLimitOneCharacter?: number;
}
export class Avatar extends React.PureComponent<AvatarProps> {
}
export interface CheckboxProps extends BoxDimensions, BoxLayout, BoxPosition, BoxSpacing, TextProps {
id?: string;
name?: string;
label?: React.ReactNode;
value?: string;
checked?: boolean;
indeterminate?: boolean;
onChange?: (e: React.ChangeEvent<string>) => void;
disabled?: boolean;
isInvalid?: boolean;
appearance?: 'default';
}
export class Checkbox extends React.PureComponent<CheckboxProps> {
}
export interface ButtonProps extends BoxDimensions, BoxLayout, BoxPosition, BoxSpacing, TextProps {
type?: 'submit' | 'button';
intent?: IntentTypes;
appearance?: 'default' | 'minimal' | 'primary';
isLoading?: boolean;
isActive?: boolean;
iconBefore?: IconNameTypes;
iconAfter?: IconNameTypes;
disabled?: boolean;
className?: string;
onClick?: (e: React.ChangeEvent<any>) => void | false | undefined;
}
export class Button extends React.PureComponent<ButtonProps> {
}
export class Card extends React.PureComponent<PaneProps> {
}
export interface IconProps {
color?: string;
icon: IconNameTypes;
size?: number;
title?: string;
style?: Record<string, string | number>;
}
export class Icon extends React.PureComponent<IconProps> {
}
export interface FormFieldProps extends BoxDimensions, BoxSpacing, BoxPosition, BoxLayout {
label: NonNullable<React.ReactNode>;
labelFor?: string;
description?: React.ReactNode;
hint?: React.ReactNode;
validationMessage?: React.ReactNode;
}
export class FormField extends React.PureComponent<FormFieldProps> {
}
export class FormFieldDescription extends React.PureComponent<ParagraphProps> {
}
export class FormFieldHint extends React.PureComponent<ParagraphProps> {
}
export interface FormFieldLabelProps extends LabelProps {
isAstrixShown?: boolean;
}
export class FormFieldLabel extends React.PureComponent<FormFieldLabelProps> {
}
export interface FormFieldValidationMessageProps extends PaneProps {
children?: React.ReactNode;
}
export class FormFieldValidationMessage extends React.PureComponent<FormFieldValidationMessageProps> {
}
export interface IconButtonProps extends ButtonProps {
icon: IconNameTypes;
iconAim?: 'down' | 'up';
iconSize?: number;
}
export class IconButton extends React.PureComponent<IconButtonProps> {
}
export interface LabelProps extends TextProps {
htmlFor?: string;
className?: string;
}
export class Label extends React.PureComponent<LabelProps> {
}
export interface MenuProps {
children: React.ReactNode[];
}
export interface MenuItemProps {
is?: string | (() => void);
onSelect?: () => void;
icon?: React.JSX;
children?: React.JSX;
secondaryText?: React.JSX;
appearance?: 'default';
intent?: IntentTypes;
}
export class Menu extends React.PureComponent<MenuProps> {
public static Item = class MenuItem extends React.PureComponent<MenuItemProps> {
};
public static Divider = class MenuDivider extends React.PureComponent {
};
}
export interface PaneProps extends UiBoxPropsType {
background?: 'tint1' | 'tint2' | 'overlay' | 'yellowTint' | 'greenTint' | 'orangeTint' | 'redTint' | 'blueTint' | 'purpleTint' | 'tealTint';
elevation?: 0 | 1 | 2 | 3 | 4;
hoverElevation?: 0 | 1 | 2 | 3 | 4;
activeElevation?: 0 | 1 | 2 | 3 | 4;
border?: string | boolean;
borderTop?: string | boolean;
borderRight?: string | boolean;
borderBottom?: string | boolean;
borderLeft?: string | boolean;
}
export class Pane extends React.PureComponent<PaneProps> {
}
export interface PopoverProps {
position?: PositionTypes;
isShown?: boolean;
trigger?: 'click' | 'hover';
content: React.ReactNode | ((object: { close: () => void }) => React.ReactNode);
children:
((props: { toggle: () => void, getRef: (ref: React.RefObject) => void, isShow: NonNullable<PopoverProps['isShown']> }) => React.ReactNode)
| React.ReactNode;
display?: string;
minWidth?: number | string;
minHeight?: number | string;
animationDuration?: number;
onOpen?: () => void;
onClose?: () => void;
onOpenComplete?: () => void;
onCloseComplete?: () => void;
onBodyClick?: () => void;
bringFocusInside?: boolean;
shouldCloseOnExternalClick?: boolean;
}
export class Popover extends React.PureComponent<PopoverProps> {
}
export interface ParagraphProps extends UiBoxPropsType {
size?: 300 | 400 | 500;
fontFamily?: 'ui' | 'display' | 'mono';
}
export class Paragraph extends React.PureComponent<ParagraphProps> {
}
export interface PositionerProps {
position?: PositionTypes;
isShown?: boolean;
children: (params: {
top: number,
left: number,
zIndex: NonNullable<StackProps['value']>,
css,
style: {
transformOrigin: string,
left: number,
top: number,
zIndex: NonNullable<StackProps['value']>,
},
getRef: (ref: React.RefObject) => void,
animationDuration: PositionerProps['animationDuration'],
state: 'exited' | 'entering' | 'entered' | 'exiting';
}) => React.ReactNode;
innerRef?: (ref: React.RefObject) => void;
bodyOffset?: number;
targetOffset?: number;
target: (params: { getRef: () => React.RefObject, isShow: boolean }) => React.ReactNode;
initialScale?: number;
animationDuration?: number;
onCloseComplete?: () => void;
onOpenComplete?: () => void;
}
export class Positioner extends React.PureComponent<PositionerProps> {
}
export interface RadioProps extends BoxSpacing, BoxPosition, BoxLayout, BoxDimensions {
id?: string;
name?: string;
label?: React.ReactNode;
value?: string;
onChange?: (e: React.ChangeEvent<any>) => void;
disabled?: boolean;
checked?: boolean;
size?: 12 | 16;
isRequired?: boolean;
isInvalid?: boolean;
appearance?: 'default';
}
export class Radio extends React.PureComponent<RadioProps> {
}
export interface RadioGroupProps extends BoxSpacing, BoxPosition, BoxLayout, BoxDimensions {
options: Array<{ label: React.ReactNode, value: string, isDisabled?: boolean }>;
value?: string;
defaultValue?: string;
onChange: (value: string) => void;
label?: string;
size?: 12 | 16;
isRequired?: boolean;
}
export class RadioGroup extends React.PureComponent<RadioGroupProps> {
}
export class SearchInput extends React.PureComponent<TextInputProps> {
}
export interface SegmentedControlProps extends BoxSpacing, BoxPosition, BoxLayout, BoxDimensions {
options: Array<{ label: string, value: NonNullable<SegmentedControlProps['value']> }>;
value?: number | string | boolean;
defaultValue?: number | string | boolean;
onChange: (value: NonNullable<SegmentedControlProps['value']>) => void;
name?: string;
height?: number;
}
export class SegmentedControl extends React.PureComponent<SegmentedControlProps> {
}
export interface SelectMenuProps {
title?: string;
width?: string | number;
height?: string | number;
options: Array<{ label: string, value: string | null }>;
onSelect?: (item: { label: string, value: string }) => void;
onDeselect?: (item: { label: string, value: string }) => void;
selected?: string | string[];
isMultiSelect?: boolean;
hasTitle?: boolean;
hasFilter?: boolean;
filterPlaceholder?: string;
filterIcon?: IconNameTypes;
onFilterChange?: (searchValue: string) => void;
position?: Omit<PositionTypes, 'left' | 'right'>;
detailView?: PopoverProps['content'];
titleView?: React.ReactNode | (() => React.ReactNode);
emptyView?: React.ReactNode | (() => React.ReactNode);
closeOnSelect?: boolean;
}
export class SelectMenu extends React.PureComponent<SelectMenuProps> {
}
export interface SideSheetProps {
children: React.ReactNode | (() => React.ReactNode);
isShown?: boolean;
onCloseComplete?: () => void;
onOpenComplete?: () => void;
onBeforeClose?: () => void;
shouldCloseOnOverlayClick?: boolean;
shouldCloseOnEscapePress?: boolean;
width?: string | number;
containerProps?: PaneProps;
position?: PICK<PositionTypes, 'top' | 'bottom' | 'left' | 'right'>;
preventBodyScrolling?: boolean;
}
export class SideSheet extends React.PureComponent<SideSheetProps> {
}
export interface SidebarTabProps extends TabProps {
}
export class SidebarTab extends React.PureComponent<SidebarTabProps> {
}
export interface StackProps {
children: (zIndex: number) => React.ReactNode;
value?: number;
}
export class Stack extends React.PureComponent<StackProps> {
}
export interface TabProps extends TextProps {
onSelect?: () => void;
isSelected?: boolean;
disabled?: boolean;
appearance?: 'default';
}
export class Tab extends React.PureComponent<TabProps> {
}
export interface TablistProps extends UiBoxPropsType {
}
export class Tablist extends React.PureComponent<TablistProps> {
}
export interface TabNavigationProps extends UiBoxPropsType {
}
export class TabNavigation extends React.PureComponent<TabNavigationProps> {
}
export interface TextProps extends UiBoxPropsType {
size?: 300 | 400 | 500 | 600;
fontFamily?: 'ui' | 'display' | 'mono';
}
export class Text extends React.PureComponent<TextProps> {
}
export interface TextInputProps extends TextProps {
id?: string;
name?: string;
type?: 'text' | 'number' | 'hidden';
required?: boolean;
disabled?: boolean;
readOnly?: boolean;
isInvalid?: boolean;
spellCheck?: boolean;
placeholder?: string;
appearance?: 'default' | 'primary';
width?: string | number;
className?: string;
value?: string | number;
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
min?: string;
max?: string;
}
export class TextInput extends React.PureComponent<TextInputProps> {
}
export interface TextInputFieldProps extends TextInputProps, FormFieldProps {
inputHeight?: number;
inputWidth?: number | string;
}
export class TextInputField extends React.PureComponent<TextInputFieldProps> {
}
export interface TooltipProps extends TextProps {
appearance?: 'default' | 'card';
position?: PositionTypes;
content: React.ReactNode;
hideDelay?: number;
isShown?: boolean;
children: React.ReactNode;
}
export class Tooltip extends React.PureComponent<TooltipProps> {
}
export interface SpinnerProps extends UiBoxPropsType {
delay?: number;
size: number;
}
export class Spinner extends React.PureComponent<SpinnerProps> {
}
} |
@Pasalietis you ought to push that up to a repo. We don't use anything without TS anymore. It's must, particularly on larger projects. That said I've liked Evergreen for a very long time, as mentioned the lack of types unfortunately is a deal breaker for our core stuff. Great start though and thx for sharing!! |
This comment has been minimized.
This comment has been minimized.
Can we please get some guidance as to whether a Typescript rewrite and/or definitions are forthcoming from the maintainers? If one is not forthcoming, can we at least get type definitions pushed to DefinitelyTyped. @Pasalietis has put together a great start above and it is poor practice to manually copy that into each project, rather have the community maintain the definitions in a central repo. |
@Pasalietis I'm still learning TypeScript and having a hard time adding the Heading Component types. For those who are using this in a project, this is what I'm doing in my package.json "scripts": {
...
"postinstall": "wget https://gist.githubusercontent.com/juxley/e516412bdfe9fde58acb082248238271/raw/c0f0783c6a78fb37854408aef19198b159a93044/index.d.ts && mv index.d.ts node_modules/evergreen-ui"
...
}, |
@Juxley typically the way to do it is to add a new type root in your tsconfig.json then have a type root in your projects named "types". So it would be: /types Not that what you're doing won't work but you may wan to investigate "type roots" in tsconfig referencing the above. Hope that helps. |
@blujedis I don't follow unfortunately, yet now the types for the Heading components works! :D The way I'm doing it is definitely not the right way...yet it's the way that's currently working until Evergreen supports types... |
@seanemmer @Pasalietis I would personally prefer to avoid putting it in DefinitelyTyped because the process to get that merged, released, updated can be fairly slow. That said, we haven't made enough meaningful progress to migrate to TypeScript. We have work started in the I'm thinking it would make sense to add a The other challenge is keeping up with drift as new changes make their way into |
@mshwery DefinitelyTyped excuse the pun is definitely not the answer. I would also arg that the proj should be natively rewritten in TS (apologies if this is already in works or pipeline). It isn't that difficult and doesn't have to be done all at once. You can get it spun up and let the comm keep contributing. Meaning you can leave many types as "any" until done and then do an official release. If you look at it as well we can't release until we have all types or have it all refactored it may really slow things. We do a ton of TS and really like EG but for our larger proj it's just not possible for us to use without TS. I sincerely believe if EG were native TS it would take off like wildfire. Commit to rewrite in TS I'll pledge one weekend a month to contrib. Just my .02 |
@blujedis see https://github.com/segmentio/evergreen/compare/typescript?expand=1 :) |
@mshwery Are you still blocked on the There are ways to use refs in function components now, so maybe a good starting point is migrating to context hooks. What do you think? |
@auderer yeah I haven't taken a look at implementing that myself so that would definitely help! The Additionally it would help trim down the React tree representation in devtools :) |
@mshwery done a lot with that recently actually (Context, useImperativeHandle etc) . If still stale in about 10 days or there about I can take a look. |
@mshwery adding a .d.ts file seems like a reasonable stopgap given the constraints and uncertain timing around a full-fledged rewrite. Should @Pasalietis make a PR with their progress so far? The community can then contribute updates (e.g. I just noticed Table is not covered) and attempt to manage the drift you mention. |
@seanemmer Yeah adding a PR with that .d.ts file might be a good first step. We can start layering in our own internal types where they differ, in follow-up PRs. |
@Pasalietis are you available to make the PR? |
@seanemmer I don't think it is suitable for PR, because it's lacking some types. I could create PR with missing components with all props as any, but it could still have some typing bugs. |
@Pasalietis I think missing types is better than no types - I've been using it as is and it's pretty easy to ts-ignore imports for untyped components. The community can then jump in and start populating the missing types. @mshwery what do you think? |
I create PR #646 with update types, but at this moment it can't be merged, because it depends on ui-box@^2.0.0 |
Alright, getting a bunch more types added here – #660 Happy to release this as-is, and we can improve upon the types (and documentation) |
https://github.com/segmentio/evergreen/releases/tag/v4.21.0 Not 100% coverage, but this should be a healthy starting point! Closing this issue for now and we can track for an actual code migration via new issues/prs |
No description provided.
The text was updated successfully, but these errors were encountered: