타입스크립트 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)
  • 태그

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

티스토리툴바