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

(WIP) Upgrade to TypeScript 4.1 #16449

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"postcss-modules": "2.0.0",
"ts-loader": "8.0.14",
"ts-jest": "24.0.1",
"typescript": "3.7.2",
"typescript": "4.1.5",
"webpack-dev-server": "4.0.0-beta.0",
"webpack-cli": "4.3.1",
"webpack": "5.21.2"
Expand All @@ -125,9 +125,11 @@
],
"nohoist": [
"packages/web-components/webpack",
"packages/web-components/@microsoft/eslint-config-fast-dna",
Copy link
Member Author

Choose a reason for hiding this comment

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

eslint-config-fast-dna also has a dep on typescript, so hopefully not hoisting it will help prevent issues.

ts-loader is tentatively using the same version now and doesn't need nohoist config.

"packages/web-components/@storybook/**",
"packages/web-components/typescript",
ecraig12345 marked this conversation as resolved.
Show resolved Hide resolved
"packages/web-components/typescript/**",
"packages/web-components/**/typescript",
Comment on lines 130 to +132
Copy link
Member Author

Choose a reason for hiding this comment

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

This very thoroughly prevents web-components' different versions of typescript from being hoisted.

  • First line: don't hoist direct dep
  • Second line: don't hoist deps of typescript (actually not needed since typescript has no deps)
  • Third line: don't hoist nested deps on typescript
    • This is important because at least two web-components deps have deps on typescript: @microsoft/api-extractor (TS 3.7.2) and @microsoft/eslint-config-fast-dna (TS 3.9.7)

"packages/web-components/ts-loader",
"packages/web-components/ts-loader/**",
"packages/web-components/ts-node",
Expand All @@ -154,19 +156,12 @@
"scripts/package.json"
],
"versionGroups": [
{
Copy link
Member Author

Choose a reason for hiding this comment

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

Not directly related but this is no longer needed; as of some previous PR test-bundles now has the same webpack version as everything else

"packages": [
"test-bundles"
],
"dependencies": [
"webpack"
]
},
{
"packages": [
"@fluentui/web-components"
],
"dependencies": [
"@microsoft/api-extractor",
"mocha",
"ts-loader",
"ts-node",
Expand Down
4 changes: 2 additions & 2 deletions packages/api-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"@fluentui/style-utilities": "^8.0.2",
"@fluentui/theme": "^2.0.2",
"@fluentui/utilities": "^8.0.2",
"@microsoft/api-extractor-model": "7.7.1",
"@microsoft/tsdoc": "0.12.14",
"@microsoft/api-extractor-model": "7.12.1",
Copy link
Member Author

Choose a reason for hiding this comment

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

Must be upgraded due to dep on typescript

"@microsoft/tsdoc": "0.12.24",
"fs-extra": "^8.1.0"
}
}
3 changes: 1 addition & 2 deletions packages/api-docs/src/tableJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ function createBasicTableJson(
description: (tsdocComment && renderDocNodeWithoutInlineTag(tsdocComment.summarySection)) || undefined,
};

const extendsArr: HeritageType[] | undefined =
!extendsTypes || Array.isArray(extendsTypes) ? extendsTypes : [extendsTypes];
const extendsArr = !extendsTypes || Array.isArray(extendsTypes) ? extendsTypes : [extendsTypes];
if (extendsArr && extendsArr.length) {
tableJson.extendsTokens = [];
for (const extendsType of extendsArr) {
Expand Down
2 changes: 1 addition & 1 deletion packages/codemods/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"tslib": "^1.10.0",
"react": "16.8.6",
"semver": "^6.2.0",
"ts-morph": "^6.0.0",
"ts-morph": "^9.1.0",
"glob": "^7.1.2",
"yargs": "^13.2.4"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0",
"typescript": "^3.5.0"
"typescript": "^3.5.0 || ^4.0.0"
},
"files": [
"src"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class FocusTrapZone extends React.Component<FocusTrapZoneProps, {}> {

_root: { current: HTMLElement | null } = { current: null };

_previouslyFocusedElementOutsideTrapZone: HTMLElement;
_previouslyFocusedElementOutsideTrapZone?: HTMLElement;
_previouslyFocusedElementInTrapZone?: HTMLElement;

_firstBumper = React.createRef<HTMLDivElement>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as React from 'react';

import * as consoleUtil from '../consoleUtil';

const TestComponent: React.FC<{ trigger?: React.ReactElement | null }> = props => {
const TestComponent: React.FC<{ trigger?: React.ReactElement }> = props => {
return useTriggerElement(props);
};

Expand All @@ -24,7 +24,7 @@ describe('useTriggerElement', () => {
});

it('"trigger" can be null', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
it('"trigger" can be null', () => {
it('"trigger" can be undefined', () => {

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 will update this shortly--I'd considered this change before but I wasn't sure if null was special and specifically needed to be supported for some reason.

const wrapper = mount(<TestComponent trigger={null} />);
const wrapper = mount(<TestComponent trigger={null as any} />);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const wrapper = mount(<TestComponent trigger={null as any} />);
const wrapper = mount(<TestComponent />);


expect(wrapper.children()).toHaveLength(0);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class RefFindNode extends React.Component<RefProps> {
componentWillUnmount() {
handleRef(this.props.innerRef, null);

delete this.prevNode;
this.prevNode = null;
Copy link
Member

Choose a reason for hiding this comment

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

@miroslavstastny this part was a fix of memory leak. Is this change safe?

Copy link
Member

Choose a reason for hiding this comment

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

Agree with @ecraig12345 - memory-leak wise, the two should be equal.

}

render() {
Expand Down
2 changes: 1 addition & 1 deletion packages/fluentui/react-component-ref/src/RefForward.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class RefForward extends React.Component<RefProps> {
}

componentWillUnmount() {
delete this.currentNode;
this.currentNode = null;
Copy link
Member

Choose a reason for hiding this comment

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

@miroslavstastny this part was a fix of memory leak. Is this change safe?

Copy link
Member Author

Choose a reason for hiding this comment

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

Unless there's some nuance that I'm not aware of, I thought that removing the reference by either deleting or setting to another value should work to address memory leaks.

Copy link
Member

Choose a reason for hiding this comment

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

Agree with @ecraig12345 - memory-leak wise, the two should be equal.

}

render() {
Expand Down
4 changes: 2 additions & 2 deletions packages/foundation-legacy/src/createComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
ITokenFunction,
IViewComponent,
} from './IComponent';
import { IDefaultSlotProps, ISlotCreator, ValidProps } from './ISlots';
import { ISlotCreator, ValidProps } from './ISlots';

/**
* Assembles a higher order component based on the following: styles, theme, view, and state.
Expand Down Expand Up @@ -84,7 +84,7 @@ export function createComponent<
tokens,
_defaultStyles: styles,
theme,
} as TViewProps & IDefaultSlotProps<any>;
} as any;

return view(viewProps);
};
Expand Down
8 changes: 6 additions & 2 deletions packages/merge-styles/src/mergeStyleSets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,19 @@ describe('mergeStyleSets', () => {
});

describe('typings tests', () => {
interface ISubComponentStyles extends IStyleSet<ISubComponentStyles> {
// TODO fix this
interface ISubComponentStyles extends Object {
// IStyleSet<ISubComponentStyles> {
root: IStyle;
}

interface ISubComponentStyleProps {
isCollapsed: boolean;
}

interface IStyles extends IStyleSet<IStyles> {
// TODO fix this
interface IStyles extends Object {
// IStyleSet<IStyles> {
root: IStyle;
subComponentStyles: {
button: IStyleFunctionOrObject<ISubComponentStyleProps, IStyleSet<ISubComponentStyles>>;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-compose/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export type ComponentWithAs<TElementType extends keyof JSX.IntrinsicElements = '

/**
* A hack to simplify the resolution for ComponentWithAs.
* @see https://github.com/microsoft/fluentui/pull/13841
* See https://github.com/microsoft/fluentui/pull/13841
Copy link
Member Author

Choose a reason for hiding this comment

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

This might have been needed due to the new API Extractor version complaining about unrecognized tags

*/
readonly __PRIVATE_PROPS?: Omit<PropsOfElement<TElementType>, 'as' | keyof TProps> & { as?: TElementType } & TProps;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function createDemoApp(appDefinition: IAppDefinition, gettingStartedPage:
// Default route.
appRoutes.push(<Route key="gettingstarted" component={gettingStartedPage} />);

const App: React.FunctionComponent<IAppProps> = props => <AppBase appDefinition={appDefinition} {...props} />;
const App: React.FunctionComponent<IAppProps> = props => <AppBase {...props} appDefinition={appDefinition} />;

routes.push(
// eslint-disable-next-line react/jsx-no-bind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ describe('SelectedPeopleList', () => {
removeButtonAriaLabel="Remove"
selectedItems={[people[0]]}
onItemsRemoved={onItemsRemoved}
onRenderItem={SelectedItem}
onRenderItem={SelectedItem as any}
/>,
);

Expand Down
10 changes: 9 additions & 1 deletion packages/react-flex/src/tmp/getStyleFromPropsAndOptions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import * as React from 'react';
import { tokensToStyleObject } from './tokensToStyleObject';
import { StyleProps, StyleOptions } from './types';
import { ColorTokenSet } from '@fluentui/theme';

export const getStyleFromPropsAndOptions = <TProps extends StyleProps, TOptions extends StyleOptions<TProps>>(
// StyleProps has a generic type parameter defaulting to ColorTokenSet.
// If we don't specify the generic here, TProps emits like this in the .d.ts:
// TProps extends StyleProps<import("@fluentui/theme").ColorTokenSet>
// and the import() causes issues for API Extractor.
export const getStyleFromPropsAndOptions = <
TProps extends StyleProps<ColorTokenSet>,
TOptions extends StyleOptions<TProps>
>(
props: TProps,
options: TOptions,
prefix?: string,
Expand Down
3 changes: 1 addition & 2 deletions packages/react-hooks/src/useControllableValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ export type ChangeCallback<

/**
* Hook to manage a value that could be either controlled or uncontrolled, such as a checked state or
* text box string.
* text box string. See https://reactjs.org/docs/uncontrolled-components.html
* @param controlledValue - The controlled value passed in the props. This value will always be used if provided,
* and the internal state will be updated to reflect it.
* @param defaultUncontrolledValue - Initial value for the internal state in the uncontrolled case.
* @returns An array of the current value and an updater callback. Like `React.useState`, the updater
* callback always has the same identity, and it can take either a new value, or a function which
* is passed the previous value and returns the new value.
* @see https://reactjs.org/docs/uncontrolled-components.html
*/
export function useControllableValue<TValue, TElement extends HTMLElement>(
controlledValue: TValue | undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ describe('getQueryParam', () => {
const realLocation = window.location;

beforeAll(() => {
delete window.location;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).location;
window.location = {} as Location;
});

Expand Down
4 changes: 2 additions & 2 deletions packages/react-tabs/src/utilities/useOverflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type OverflowItemsChangedCallback = (
items: { ele: HTMLElement; isOverflowing: boolean }[],
) => void;

/** Parameters for {@see useOverflow} */
/** Parameters for `useOverflow` */
export type OverflowParams = {
/** Callback to notify the user that the items in the overflow have changed. */
onOverflowItemsChanged: OverflowItemsChangedCallback;
Expand All @@ -27,7 +27,7 @@ export type OverflowParams = {
pinnedIndex?: number;
};

/** Return value for {@see useOverflow} */
/** Return value for `useOverflow` */
export type OverflowRefs = {
/** Set the overflow menu button's ref to this ref callback */
menuButtonRef: RefCallback<HTMLElement>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import * as React from 'react';
import { CalendarDayBase } from './CalendarDay.base';
import { styles } from './CalendarDay.styles';
import { styled } from '../../../Utilities';
import { ICalendarDayProps } from './CalendarDay.types';

export const CalendarDay = styled(CalendarDayBase, styles, undefined, { scope: 'CalendarDay' });
export const CalendarDay: React.FunctionComponent<ICalendarDayProps> = styled(CalendarDayBase, styles, undefined, {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is required to prevent inferred imports in the .d.ts, which API Extractor now complains about.

I think I'm going to separate out this and the other date-time stuff into another PR, because it also included some general types cleanup to more accurately reflect actual usage.

scope: 'CalendarDay',
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as React from 'react';
import { CalendarMonthBase } from './CalendarMonth.base';
import { getStyles } from './CalendarMonth.styles';
import { styled } from '../../../Utilities';
import { ICalendarMonthProps } from './CalendarMonth.types';

export const CalendarMonth = styled(CalendarMonthBase, getStyles, undefined, { scope: 'CalendarMonth' });
export const CalendarMonth: React.FunctionComponent<ICalendarMonthProps> = styled(
CalendarMonthBase,
getStyles,
undefined,
{ scope: 'CalendarMonth' },
);
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ interface ICalendarYearGrid {
focus(): void;
}

interface ICalendarYearGridCellProps extends ICalendarYearProps {
interface ICalendarYearGridCellProps extends Omit<ICalendarYearProps, 'ref'> {
year: number;
current?: boolean;
selected?: boolean;
Expand All @@ -35,7 +35,7 @@ interface ICalendarYearGridCellProps extends ICalendarYearProps {
onRenderYear?: (year: number) => React.ReactNode;
}

interface ICalendarYearGridProps extends ICalendarYearProps, ICalendarYearRange {
interface ICalendarYearGridProps extends Omit<ICalendarYearProps, 'ref'>, ICalendarYearRange {
selectedYear?: number;
animateBackwards?: boolean;
componentRef?: IRefObject<ICalendarYearGridCell>;
Expand Down Expand Up @@ -437,45 +437,46 @@ function useYearRangeState({ selectedYear, navigatedYear }: ICalendarYearProps)
return [fromYear, toYear, onNavNext, onNavPrevious] as const;
}

export const CalendarYearBase = React.forwardRef(
(props: ICalendarYearProps, forwardedRef: React.Ref<HTMLDivElement>) => {
const animateBackwards = useAnimateBackwards(props);
const [fromYear, toYear, onNavNext, onNavPrevious] = useYearRangeState(props);
export const CalendarYearBase: React.FunctionComponent<ICalendarYearProps> = React.forwardRef<
HTMLDivElement,
ICalendarYearProps
>(({ ref: unusedRef, ...props }, forwardedRef) => {
const animateBackwards = useAnimateBackwards(props);
const [fromYear, toYear, onNavNext, onNavPrevious] = useYearRangeState(props);

const gridRef = React.useRef<ICalendarYearGrid>(null);
const gridRef = React.useRef<ICalendarYearGrid>(null);

React.useImperativeHandle(props.componentRef, () => ({
focus() {
gridRef.current?.focus?.();
},
}));
React.useImperativeHandle(props.componentRef, () => ({
focus() {
gridRef.current?.focus?.();
},
}));

const { styles, theme, className } = props;
const { styles, theme, className } = props;

const classNames = getClassNames(styles, {
theme: theme!,
className: className,
});
const classNames = getClassNames(styles, {
theme: theme!,
className: className,
});

return (
<div className={classNames.root} ref={forwardedRef}>
<CalendarYearHeader
{...props}
fromYear={fromYear}
toYear={toYear}
onSelectPrev={onNavPrevious}
onSelectNext={onNavNext}
animateBackwards={animateBackwards}
/>
<CalendarYearGrid
{...props}
fromYear={fromYear}
toYear={toYear}
animateBackwards={animateBackwards}
componentRef={gridRef}
/>
</div>
);
},
);
return (
<div className={classNames.root} ref={forwardedRef}>
<CalendarYearHeader
{...props}
fromYear={fromYear}
toYear={toYear}
onSelectPrev={onNavPrevious}
onSelectNext={onNavNext}
animateBackwards={animateBackwards}
/>
<CalendarYearGrid
{...props}
fromYear={fromYear}
toYear={toYear}
animateBackwards={animateBackwards}
componentRef={gridRef}
/>
</div>
);
});
CalendarYearBase.displayName = 'CalendarYearBase';
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as React from 'react';
import { getStyles } from './CalendarYear.styles';
import { styled } from '../../../Utilities';
import { CalendarYearBase } from './CalendarYear.base';
import { ICalendarYearProps } from './CalendarYear.types';

export const CalendarYear = styled(CalendarYearBase, getStyles, undefined, { scope: 'CalendarYear' });
export const CalendarYear: React.FunctionComponent<ICalendarYearProps> = styled(
CalendarYearBase,
getStyles,
undefined,
{ scope: 'CalendarYear' },
);
Loading