React Native로 권한을 제공해야 하는 커스텀 훅을 만들기 위해서 작업을 하는 도중 타입을 선언하는 과정에서
새로운 경험을 하게 되었다.
import {
checkMultiple,
PERMISSIONS,
PermissionStatus,
requestMultiple,
RESULTS,
} from 'react-native-permissions';
import usePlatform from './usePlatform';
import {useEffect} from 'react';
type AndroidPermissions =
(typeof PERMISSIONS.ANDROID)[keyof typeof PERMISSIONS.ANDROID];
type IOSPermissions = (typeof PERMISSIONS.IOS)[keyof typeof PERMISSIONS.IOS];
interface Permissions {
android: AndroidPermissions[];
ios: IOSPermissions[];
}
const usePermission = (permissions: Permissions) => {
const {isIOS} = usePlatform();
const platformPermissions = isIOS ? permissions.ios : permissions.android;
const checkGranted = (
statuses: Record<AndroidPermissions | IOSPermissions, PermissionStatus>,
) => {
return platformPermissions.every(
permission => statuses[permission] === RESULTS.GRANTED,
);
};
const requestPermission = async () => {
const statuses = await checkMultiple(platformPermissions);
if (checkGranted(statuses)) {
// 권한 존재
} else {
const requestStatuses = await requestMultiple(platformPermissions);
if (checkGranted(requestStatuses)) {
// 권한 승인
} else {
// 권한 존재 X
}
}
};
useEffect(() => {
requestPermission;
}, []);
};
export default usePermission;
전체적인 코드는 이렇게 구성되어 있는데, 아직 작업 중인 코드라서 완성도는 낮다...
해당 경험을 하고 호다닥 작성하고 싶어서 메모를 남기고 글을 작성하는 중
keyof
import {
checkMultiple,
PERMISSIONS,
PermissionStatus,
requestMultiple,
RESULTS,
} from 'react-native-permissions';
// ...
type AndroidPermissions =
(typeof PERMISSIONS.ANDROID)[keyof typeof PERMISSIONS.ANDROID];
type IOSPermissions = (typeof PERMISSIONS.IOS)[keyof typeof PERMISSIONS.IOS];
interface Permissions {
android: AndroidPermissions[];
ios: IOSPermissions[];
}
react-native-permissions 패키지를 사용하는데, 매개변수로 넘겨받는 값이 PERMISSIONS 객체의 value로 구성된 배열이다.
types를 제공하는지 찾아봤는데 따로 types는 제공하지 않는 것 같아서 어떤 방법을 사용해야하나 고민을 하고 있었는데, keyof라는 키워드를 사용하면 객체의 키값을 받아올 수 있었다.
type AndroidPermissions =
(typeof PERMISSIONS.ANDROID)[keyof typeof PERMISSIONS.ANDROID];
이걸로 PERMISSIONS.ANDROID의 타입에게 동일한 타입의 kay값으로 value를 추출할 수 있다는 것을 알았다.
{
ACCEPT_HANDOVER: 'android.permission.ACCEPT_HANDOVER';
ACCESS_BACKGROUND_LOCATION: 'android.permission.ACCESS_BACKGROUND_LOCATION';
ACCESS_COARSE_LOCATION: 'android.permission.ACCESS_COARSE_LOCATION';
ACCESS_FINE_LOCATION: 'android.permission.ACCESS_FINE_LOCATION';
}
다음과 같은 값이 PERMISSION.ANDROID의 타입이라고 생각해보자.
여기서 keyof typeof pERMISSIONS.ANDROID는 다음과 같다.
'ACCEPT_HANDOVER' | 'ACCESS_BACKGROUND_LOCATION' | 'ACCESS_COARSE_LOCATION' | 'ACCESS_FINE_LOCATION'
이렇게 구성된 값을 (typeof PERMISSIONS.ANDROID)[keyof typeof PERMISSIONS.ANDROID] 이렇게 사용한다면
객체의 value만 뚝하고 나오게 되는 것이다.
'android.permission.ACCEPT_HANDOVER' | 'android.permission.ACCESS_BACKGROUND_LOCATION' | 'android.permission.ACCESS_COARSE_LOCATION' | 'android.permission.ACCESS_FINE_LOCATION'
객체의 value를 가지고 오는 방식이 조금 더 까다롭긴 하지만 불가능한 것이 아니며 자주 사용될 방법이라고 생각한다.
Record
const checkGranted = (
statuses: Record<AndroidPermissions | IOSPermissions, PermissionStatus>,
) => {
return platformPermissions.every(
permission => statuses[permission] === RESULTS.GRANTED,
);
};
앞서 만든 Permissions들을 key값으로 가지고 있지만 value는 새롭게 구성된 값으로 만들어질 때 사용할 수 있는 것이 Record이다.
Record<K, V>
키가 K 타입이고 값은 V로 구성되는 타입을 만들어주는 유틸 타입이다.
객체 형식으로 인터페이스를 만들어서 타입을 지정해줄 수 있지만 Record를 사용하면 간단해서 동일한 기능을 구현할 수 있기 때문에 사용하면 개발의 질이 올라갈 것 같다.
'TypeScript > 실험실' 카테고리의 다른 글
[TypeScript] Webpack 환경에서 TypeScript 사용하기 (0) | 2022.10.02 |
---|