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

(BSR) refactor(typescript): delete some noUncheckedIndexedAccess #7466

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
39 changes: 3 additions & 36 deletions scripts/noUncheckedIndexedAccess_snapshot.txt
bebstein-pass marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
./src/cheatcodes/hooks/useSomeOfferId.ts:24
./src/features/bookOffer/components/BookHourChoice.tsx:122
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:35
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:41
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:59
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:61
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:72
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:74
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:85
./src/features/bookOffer/components/Calendar/useMarkedDates.native.test.ts:87
./src/features/bookOffer/helpers/useReviewInAppInformation.ts:16
./src/features/bookOffer/helpers/useRotatingText.ts:44
./src/features/bookOffer/helpers/useRotatingText.ts:47
./src/features/bookOffer/helpers/useRotatingText.ts:54
./src/features/bookOffer/helpers/useRotatingText.ts:57
./src/features/culturalSurvey/helpers/useGetNextQuestion.ts:13
./src/features/culturalSurvey/pages/CulturalSurveyQuestions.native.test.tsx:234
./src/features/deeplinks/helpers/getScreenFromDeeplink.ts:13
./src/features/deeplinks/helpers/getScreenFromDeeplink.ts:15
./src/features/deeplinks/helpers/getScreenFromDeeplink.ts:17
./src/features/deeplinks/helpers/getScreenFromDeeplink.ts:19
./src/features/deeplinks/helpers/getScreenFromDeeplink.ts:22
./src/features/deeplinks/helpers/getScreenFromDeeplink.ts:24
./src/features/home/api/helpers/mapVenuesDataAndModules.ts:13
./src/features/home/api/helpers/mapVenuesDataAndModules.ts:15
./src/features/home/components/modules/OffersModule.tsx:69
Expand All @@ -36,21 +15,15 @@
./src/features/navigation/RootNavigator/linking/getNestedNavigationFromState.ts:14
./src/features/navigation/RootNavigator/linking/getNestedNavigationFromState.ts:16
./src/features/navigation/RootNavigator/linking/getNestedNavigationFromState.ts:19
./src/features/navigation/RootNavigator/linking/getScreenConfig.test.ts:75
./src/features/navigation/RootNavigator/linking/getScreenConfig.test.ts:81
./src/features/navigation/RootNavigator/linking/getScreenConfig.test.ts:87
./src/features/navigation/RootNavigator/linking/getScreenConfig.test.ts:93
./src/features/navigation/RootNavigator/linking/getScreenConfig.test.ts:99
./src/features/navigation/helpers/useCurrentRoute.ts:4
./src/features/navigation/helpers/usePreviousRoute.ts:4
./src/features/navigation/sanitizeNavigationState.ts:5
./src/features/offer/components/OfferPlaylistList/OfferPlaylistList.native.test.tsx:110
./src/features/offer/components/OfferPlaylistList/OfferPlaylistList.native.test.tsx:76
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:74
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:76
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:81
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:83
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:85
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:80
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:82
./src/features/offer/components/VenueSelectionListItem/VenueSelectionListItem.web.tsx:84
./src/features/profile/components/CreditInfo/CreditProgressBar.tsx:32
./src/features/search/components/sections/Accessibility/Accessibility.tsx:33
./src/features/search/pages/SuggestedPlacesOrVenues/SuggestedVenues.native.test.tsx:43
Expand All @@ -64,12 +37,6 @@
./src/libs/itinerary/useItinerary.native.test.ts:61
./src/libs/itinerary/useItinerary.ts:101
./src/libs/itinerary/useItinerary.ts:77
./src/libs/location/geolocation/requestGeolocPermission/requestGeolocPermission.android.ts:11
./src/libs/location/geolocation/requestGeolocPermission/requestGeolocPermission.android.ts:15
./src/libs/location/geolocation/requestGeolocPermission/requestGeolocPermission.android.ts:17
./src/libs/location/geolocation/requestGeolocPermission/requestGeolocPermission.android.ts:22
./src/libs/location/geolocation/requestGeolocPermission/requestGeolocPermission.android.ts:24
./src/libs/location/geolocation/requestGeolocPermission/requestGeolocPermission.android.ts:9
./src/libs/parsers/formatDates.ts:105
./src/libs/parsers/formatDates.ts:107
./src/libs/parsers/formatDates.ts:112
Expand Down
7 changes: 5 additions & 2 deletions src/cheatcodes/hooks/useSomeOfferId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ export const useSomeOfferId = () => {
aroundPlaceRadius: 'all',
},
})
// @ts-expect-error: because of noUncheckedIndexedAccess
.then((response) => setOfferId(Number.parseInt(response.hits[0].objectID)))
.then((response) => {
if (response.hits[0]) {
setOfferId(Number.parseInt(response.hits[0].objectID))
}
})
.catch(() => {
// The cheatcodes are only in testing
// eslint-disable-next-line no-console
Expand Down
3 changes: 1 addition & 2 deletions src/features/bookOffer/components/BookHourChoice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ export const BookHourChoice = () => {

const selectHour = (hour: string, stockFromHour: OfferStockResponse[]) => {
dispatch({ type: 'SELECT_HOUR', payload: hour })
if (stockFromHour.length === 1) {
// @ts-expect-error: because of noUncheckedIndexedAccess
if (stockFromHour.length === 1 && stockFromHour[0]) {
dispatch({ type: 'SELECT_STOCK', payload: stockFromHour[0].id })
}
if (!isDuo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ describe('useMarkedDates()', () => {
it('should mark selected date correctly', () => {
let hook = renderHook(() => useMarkedDates([offerStockResponseSnap], credit))

// @ts-expect-error: because of noUncheckedIndexedAccess
expect(hook.result.current['2021-01-01'].selected).toBe(true)
expect(hook.result.current['2021-01-01']?.selected).toBe(true)

mockBookingState.date = new Date(2021, 4, 4)
hook = renderHook(() => useMarkedDates([offerStockResponseSnap], credit))

// @ts-expect-error: because of noUncheckedIndexedAccess
expect(hook.result.current['2021-01-01'].selected).toBe(false)
expect(hook.result.current['2021-01-01']?.selected).toBe(false)
})

it('should skip stocks without date', () => {
Expand All @@ -56,10 +54,8 @@ describe('useMarkedDates()', () => {
]
const { result } = renderHook(() => useMarkedDates(stocks, 2000))

// @ts-expect-error: because of noUncheckedIndexedAccess
expect(result.current['2021-01-01'].price).toEqual(2000)
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(result.current['2021-01-01'].status).toEqual('BOOKABLE')
expect(result.current['2021-01-01']?.price).toEqual(2000)
expect(result.current['2021-01-01']?.status).toEqual('BOOKABLE')
})

it('should return the correct status and price for non bookable stocks', () => {
Expand All @@ -69,10 +65,8 @@ describe('useMarkedDates()', () => {
]
const { result } = renderHook(() => useMarkedDates(stocks, 2000))

// @ts-expect-error: because of noUncheckedIndexedAccess
expect(result.current['2021-01-01'].price).toEqual(200)
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(result.current['2021-01-01'].status).toEqual('NOT_BOOKABLE')
expect(result.current['2021-01-01']?.price).toEqual(200)
expect(result.current['2021-01-01']?.status).toEqual('NOT_BOOKABLE')
})

it('should select the bookable stock for a particular date even if not enough credit', () => {
Expand All @@ -82,9 +76,7 @@ describe('useMarkedDates()', () => {
]
const { result } = renderHook(() => useMarkedDates(stocks, 200))

// @ts-expect-error: because of noUncheckedIndexedAccess
expect(result.current['2021-01-01'].price).toEqual(2000)
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(result.current['2021-01-01'].status).toEqual('NOT_BOOKABLE')
expect(result.current['2021-01-01']?.price).toEqual(2000)
expect(result.current['2021-01-01']?.status).toEqual('NOT_BOOKABLE')
})
})
12 changes: 4 additions & 8 deletions src/features/bookOffer/helpers/useRotatingText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,15 @@ export function useRotatingText<T extends RotatingTextOptions[]>(
}

// the condition handles loop repetition from start
// @ts-expect-error: because of noUncheckedIndexedAccess
return currentMessage.keepDuration ? 0 : prev
return currentMessage?.keepDuration ? 0 : prev
})
// @ts-expect-error: because of noUncheckedIndexedAccess
}, currentMessage.keepDuration)
}, currentMessage?.keepDuration)
}

return () => {
clearInterval(intervalRef.current)
}
// @ts-expect-error: because of noUncheckedIndexedAccess
}, [currentMessage.keepDuration, shouldRun])
}, [currentMessage?.keepDuration, shouldRun])

// @ts-expect-error: because of noUncheckedIndexedAccess
return currentMessage.message
return currentMessage?.message ?? ''
}
9 changes: 3 additions & 6 deletions src/features/culturalSurvey/helpers/useGetNextQuestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ export const useGetNextQuestion = (currentQuestion: CulturalSurveyQuestionEnum)
const nextQuestionIndex = questionsToDisplay.indexOf(currentQuestion) + 1

const isCurrentQuestionLastQuestion = nextQuestionIndex === questionsToDisplay.length
let nextQuestion = currentQuestion

if (!isCurrentQuestionLastQuestion) {
// @ts-expect-error: because of noUncheckedIndexedAccess
nextQuestion = questionsToDisplay[nextQuestionIndex]
}
const nextQuestion = isCurrentQuestionLastQuestion
? currentQuestion
: questionsToDisplay[nextQuestionIndex]

return { isCurrentQuestionLastQuestion, nextQuestion }
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export function CulturalSurveyQuestions({ route }: CulturalSurveyQuestionsProps)
const navigateToNextQuestion = () => {
if (isCurrentQuestionLastQuestion) {
postCulturalSurveyAnswers({ answers })
} else {
} else if (nextQuestion) {
Copy link
Contributor

Choose a reason for hiding this comment

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

il se passe quoi si isCurrentQuestionLastQuestion est falsy et que nextQuestion est aussi falsy ?

Copy link
Contributor

Choose a reason for hiding this comment

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

rien ne se passe, le type n'autorisait pas de push une nextQuestion à undefined, il y a peut-être du métier à revoir, en cas de doute je peux revert ce code

push('CulturalSurveyQuestions', { question: nextQuestion })
}
}
Expand Down
16 changes: 5 additions & 11 deletions src/features/deeplinks/helpers/getScreenFromDeeplink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,13 @@ export function getScreenFromDeeplink(url: string): DeeplinkParts {
}
const navigationState = linking.getStateFromPath(pathWithQueryString, linking.config)
const route = getLastRouteFromState(navigationState)
// @ts-expect-error: because of noUncheckedIndexedAccess
const screen = route.name
// @ts-expect-error: because of noUncheckedIndexedAccess
let params = route.params
// @ts-expect-error: because of noUncheckedIndexedAccess
if (route.state) {
// @ts-expect-error: because of noUncheckedIndexedAccess
const screen = route?.name
let params = route?.params
if (route?.state) {
const nestedRoute = getLastRouteFromState(route.state)
params = {
// @ts-expect-error: because of noUncheckedIndexedAccess
screen: nestedRoute.name,
// @ts-expect-error: because of noUncheckedIndexedAccess
params: nestedRoute.params,
screen: nestedRoute?.name,
params: nestedRoute?.params,
}
}
return { screen, params } as DeeplinkParts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,32 +72,27 @@ describe('getScreensAndConfig()', () => {
_DeeplinkOnlyLogin1: { path: 'connexion', parse },
})
expect(Screens).toHaveLength(5)
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(Screens[0].props).toEqual({
expect(Screens[0]?.props).toEqual({
name: 'Offer',
component: expect.any(Object),
options: { title: 'Offer title' },
})
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(Screens[1].props).toEqual({
expect(Screens[1]?.props).toEqual({
name: '_DeeplinkOnlyOffer1',
component: expect.any(Object),
options: { title: 'Offer title' },
})
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(Screens[2].props).toEqual({
expect(Screens[2]?.props).toEqual({
name: '_DeeplinkOnlyOffer2',
component: expect.any(Object),
options: { title: 'Offer title' },
})
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(Screens[3].props).toEqual({
expect(Screens[3]?.props).toEqual({
name: 'Login',
component: expect.any(Object),
options: { title: 'Login title' },
})
// @ts-expect-error: because of noUncheckedIndexedAccess
expect(Screens[4].props).toEqual({
expect(Screens[4]?.props).toEqual({
name: '_DeeplinkOnlyLogin1',
component: expect.any(Object),
options: { title: 'Login title' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ export function VenueSelectionListItem({ index, style, data }: Readonly<RowProps
<SelectableListItem
// @ts-expect-error: because of noUncheckedIndexedAccess
bebstein-pass marked this conversation as resolved.
Show resolved Hide resolved
onSelect={() => data.onItemSelect(data.items[index].offerId)}
// @ts-expect-error: because of noUncheckedIndexedAccess
isSelected={data.selectedItem === data.items[index].offerId}
isSelected={data.selectedItem === data.items[index]?.offerId}
testID="venue-selection-list-item"
render={({ isHover }) => (
<VenueDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,22 @@ import { AskGeolocPermission } from 'libs/location/types'

import { GeolocPermissionState } from '../enums'

const ACCESS_FINE_LOCATION = 'android.permission.ACCESS_FINE_LOCATION'
const ACCESS_COARSE_LOCATION = 'android.permission.ACCESS_COARSE_LOCATION'

const requestGeolocPermissionSystem: AskGeolocPermission = async () => {
const permissions = await PermissionsAndroid.requestMultiple([
// @ts-expect-error: because of noUncheckedIndexedAccess
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
// @ts-expect-error: because of noUncheckedIndexedAccess
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION,
])
Comment on lines +7 to 14
Copy link
Contributor Author

@xlecunff-pass xlecunff-pass Jan 2, 2025

Choose a reason for hiding this comment

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

le type de PermissionsAndroid.PERMISSIONS est un record qui a comme valeurs des strings (très permissif) donc on ne peut pas compter dessus pour un fort typage.

PermissionsAndroid.requestMultiple a un typage fort sur le tableau de permissions qui peut lui être passés mais ne fourni pas d'enum de ces strings :(

Copy link
Contributor

Choose a reason for hiding this comment

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

est-ce qu'il serait facile, rapide et pertinent de faire une PR pour améliorer le typage de react-native ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Il y a une possibilité de créer cet Enum dans notre projet, à voire ensuite pour la maintenabilité.
Avec la méthode ci-dessus, si une autorisation change ou n'existe plus, Typescript ne sera pas content des paramètres qui lui seront passés, même si à priori ça a l'air d'être des plain strings

Copy link
Contributor

Choose a reason for hiding this comment

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

je proposais de faire une PR sur le projet upstream react-native (pour faire par exemple un enum)

if (
// @ts-expect-error: because of noUncheckedIndexedAccess
permissions[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] === 'granted' ||
// @ts-expect-error: because of noUncheckedIndexedAccess
permissions[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] === 'granted'
permissions[ACCESS_FINE_LOCATION] === 'granted' ||
permissions[ACCESS_COARSE_LOCATION] === 'granted'
) {
return GeolocPermissionState.GRANTED
} else if (
// @ts-expect-error: because of noUncheckedIndexedAccess
permissions[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] === 'never_ask_again' ||
// @ts-expect-error: because of noUncheckedIndexedAccess
permissions[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] === 'never_ask_again'
permissions[ACCESS_FINE_LOCATION] === 'never_ask_again' ||
permissions[ACCESS_COARSE_LOCATION] === 'never_ask_again'
) {
return GeolocPermissionState.NEVER_ASK_AGAIN
}
Expand Down
Loading