타입스크립트 keyof, Record

2024. 9. 11. 18:12·TypeScript/실험실
반응형

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
'TypeScript/실험실' 카테고리의 다른 글
  • [TypeScript] Webpack 환경에서 TypeScript 사용하기
잉여개발자
잉여개발자
풀스택 개발자를 목표로 잉여롭게 개발 공부도 하면서 다양한 취미 생활도 즐기고 있는 잉여 개발자입니다.
  • 잉여개발자
    잉여로운 개발일지
    잉여개발자
    • 분류 전체보기 (789)
      • 개발정보 (36)
      • 개발환경 (7)
      • 개발생활 (19)
      • React (141)
        • 이론 (23)
        • 기능 (12)
        • 실험실 (88)
        • 버그 (6)
        • 패스트캠퍼스 (9)
        • Npm (3)
      • React Native (28)
        • 공통 (6)
        • TypeScript (3)
        • JavaScript (18)
        • 버그 (1)
      • Next.js (30)
        • 이론 (13)
        • 실험실 (13)
        • 버그 (3)
      • Web (35)
      • 알고리즘 (202)
        • 풀이 힌트 (39)
      • JavaScript (47)
      • TypeScript (29)
        • 기초 (27)
        • 실험실 (2)
      • Node.js (13)
        • 이론 (0)
        • 기능 (3)
        • 실험실 (9)
        • 버그 (1)
      • 도커 (4)
      • CCNA (22)
        • 이론 (4)
        • 문제 (18)
      • 취미생활 (167)
        • 잉여로운 칵테일 (2)
        • 잉여의 식물키우기 (130)
        • 잉여로운 여행기 (11)
        • 잉여의 제2외국어 (21)
        • 잉여로운 책장 (2)
      • Java (1)
        • Java의 정석 (1)
      • 꿀팁 공유 (3)
  • 태그

    next.js
    바질 키우기
    프로그래머스
    네이버 부스트캠프
    Node.js
    다이소
    webpack
    Docker
    자바스크립트
    react
    CCNA
    Babel
    ChatGPT
    타입스크립트
    ReactNative
    알고리즘
    타일러영어
    영어회화
    영어독학
    javascript
    리얼학습일기
    redux
    바질
    덤프
    CSS
    네트워크
    식물
    리액트
    리얼클래스
    typescript
  • hELLO· Designed By정상우.v4.10.1
잉여개발자
타입스크립트 keyof, Record
상단으로

티스토리툴바