chore: add stronger types to several files (#28347)

Issue number: Internal

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

As part of FW-2832, the team would like to swap out usages of the any
type for stronger types.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->


c529bc23f1
- `scrollToTop` doesn't return anything, so I added the `void` return
type


a96971ad28
- `animation.effect` is a type of
[AnimationEffect](https://developer.mozilla.org/en-US/docs/Web/API/Animation/effect).
One of the more common types of effects is a `KeyframeEffect`. However,
TypeScript doesn't know which specific type of AnimationEffect we are
using, so I cast `animation.effect` as KeyframeEffect where appropriate.
- I also added `!` to places where we know the effect and other
properties are always defined (since they run after the web animation
has been constructed)
- Added stronger types to the internal to/from/fromTo functions (the
public facing type improvements are in
https://github.com/ionic-team/ionic-framework/pull/28334)


fdaf550059
- `getRootNode` can return multiple types of objects, so I cast it to
the specific types that we work with in `isFocused`.


46a6efa510
- Added the "Animation" type and resolved related errors once we had
stronger types


a7cb9a5685
- Made heavier use of the `T` generic
- Once we know `node` is an Element (`nodeType === 1`) we manually cast
the element as `T`


6a9d1f095d
- The focus visible utility is an internal utility, but it was lacking
an interface, so I added one.


90b64c2de5
- Removed unneeded HTMLElement casting
- Added `!` since we can assume the selected elements are defined with
the refresher
- Added documentation as to why casting `referencEl.style` as `any` is
something we need to keep.


3a084caf83
- Avoided the Event naming collision by using globalThis

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Note: This PR contains only type changes. Changes the required updates
to the implementation of Ionic are pulled out into separate PRs and
target a minor release branch to minimize risk.

---------

Co-authored-by: Amanda Johnston <90629384+amandaejohnston@users.noreply.github.com>
This commit is contained in:
Liam DeBeasi
2023-10-23 12:46:42 -04:00
committed by GitHub
parent 331c08aad5
commit 15a02253d3
10 changed files with 98 additions and 45 deletions

View File

@ -1,5 +1,6 @@
import type { ComponentInterface } from '@stencil/core';
import { Build, Component, Element, Host, Method, h } from '@stencil/core';
import type { FocusVisibleUtility } from '@utils/focus-visible';
import { isPlatform } from '@utils/platform';
import { config } from '../../global/config';
@ -10,7 +11,7 @@ import { getIonMode } from '../../global/ionic-global';
styleUrl: 'app.scss',
})
export class App implements ComponentInterface {
private focusVisible?: any; // TODO(FW-2832): type
private focusVisible?: FocusVisibleUtility;
@Element() el!: HTMLElement;

View File

@ -33,7 +33,7 @@ const focusableQueryString =
shadow: true,
})
export class Menu implements ComponentInterface, MenuI {
private animation?: any; // TODO(FW-2832): type
private animation?: Animation;
private lastOnEnd = 0;
private gesture?: Gesture;
private blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
@ -491,11 +491,11 @@ export class Menu implements ComponentInterface, MenuI {
this.animation = undefined;
}
// Create new animation
this.animation = await menuController._createAnimation(this.type!, this);
const animation = (this.animation = await menuController._createAnimation(this.type!, this));
if (!config.getBoolean('animated', true)) {
this.animation.duration(0);
animation.duration(0);
}
this.animation.fill('both');
animation.fill('both');
}
private async startAnimation(shouldOpen: boolean, animated: boolean): Promise<void> {

View File

@ -136,8 +136,7 @@ export class Radio implements ComponentInterface {
/** @internal */
@Method()
async setFocus(ev: any) {
// TODO(FW-2832): type (using Event triggers a build error due to conflict with Stencil Event import)
async setFocus(ev: globalThis.Event) {
ev.stopPropagation();
ev.preventDefault();

View File

@ -25,12 +25,11 @@ export const createPullingAnimation = (
};
const createBaseAnimation = (pullingRefresherIcon: HTMLElement) => {
// TODO(FW-2832): add types/re-evaluate asserting so many things
const spinner = pullingRefresherIcon.querySelector('ion-spinner') as HTMLElement;
const circle = spinner!.shadowRoot!.querySelector('circle') as any;
const spinnerArrowContainer = pullingRefresherIcon.querySelector('.spinner-arrow-container') as HTMLElement;
const spinner = pullingRefresherIcon.querySelector('ion-spinner')!;
const circle = spinner!.shadowRoot!.querySelector('circle')!;
const spinnerArrowContainer = pullingRefresherIcon.querySelector('.spinner-arrow-container')!;
const arrowContainer = pullingRefresherIcon!.querySelector('.arrow-container');
const arrow = arrowContainer ? (arrowContainer!.querySelector('ion-icon') as HTMLElement) : null;
const arrow = arrowContainer ? arrowContainer!.querySelector('ion-icon') : null;
const baseAnimation = createAnimation().duration(1000).easing('ease-out');
@ -210,6 +209,14 @@ export const shouldUseNativeRefresher = async (referenceEl: HTMLIonRefresherElem
return (
pullingSpinner !== null &&
refreshingSpinner !== null &&
/**
* We use webkitOverflowScrolling for feature detection with rubber band scrolling
* on iOS. When doing referenceEl.style, webkitOverflowScrolling is undefined on non-iOS platforms.
* However, it will be the empty string on iOS.
* Note that we do not use getPropertyValue (and thus need to cast as any) because calling
* getPropertyValue('-webkit-overflow-scrolling') will return the empty string if it is not
* set on the element, even if the platform does not support that.
*/
((mode === 'ios' && isPlatform('mobile') && (referenceEl.style as any).webkitOverflowScrolling !== undefined) ||
mode === 'md')
);