1

I have difficult time to explain this, maybe pictures of my code can help

I am able to do conditional type like this

if first parameter is 'FIRST_KEY', the second parameter must be number

then if first parameter is 'SECOND_KEY', the second parameter must be a boolean

enter image description here

enter image description here

This is my successful approach

enter image description here

then i want to do the same but in an array like this

enter image description here

and i have no idea to make the typescript to work in that situation

here is my helper code and the type

i thought it gives better information using screenshots visually like this

enter image description here

Here is the code in text

helpers/local-storage.ts

import AsyncStorage from "@react-native-async-storage/async-storage"

import { localStorageType } from '../references/types/local-storage'

async function getItem<keyType extends keyof localStorageType>(key: keyType) {
  return await AsyncStorage.getItem(key)
}

async function multiGet<keyType extends (keyof localStorageType)[]>(keys: keyType) {
  return await AsyncStorage.multiGet(keys)
}

async function setItem<keyType extends keyof localStorageType, pickedlocalStorageType extends localStorageType[keyType]>(key: keyType, savedData: pickedlocalStorageType) {
  await AsyncStorage.setItem(key, typeof savedData != 'string' ? JSON.stringify(savedData) : savedData)
}

async function multiSet()  {
  
}

multiSet([
  ['FIRST_KEY', 8],
  ['THIRD_KEY', 'test'],
])

async function removeItem<keyType extends keyof localStorageType>(key: keyType) {
  await AsyncStorage.removeItem(key)
}

async function multiRemove<keyType extends (keyof localStorageType)[]>(keys: keyType) {
  return await AsyncStorage.multiRemove(keys)
}

async function clear() {
  await AsyncStorage.clear()
}

export default {
  getItem,
  multiGet,
  setItem,
  multiSet,
  removeItem,
  multiRemove,
  clear
}

types/local-storage.ts

export type localStorageType = {
  FIRST_KEY: number,
  SECOND_KEY: boolean,
  THIRD_KEY: string
}

thanks

2
  • 1
    Don't post pictures of your code, but your code itself, please. Commented Mar 17, 2021 at 13:57
  • @jperl okay thanks, I add my code below my screenshots Commented Mar 17, 2021 at 14:01

2 Answers 2

2

Given a structure T, this type

type Pair<T> = {
    [K in keyof T]: [K, T[K]];
} [keyof T];

creates a Union of all possible key-value pairs (that is, ['FIRST',string] | ['SECOND',number] | etc...

Thus, the parameter of multiSet should be Array<Pair<localStorageType>>

Note that this type allows keys to be in arbitrary order and be repeated, so for example, this would be valid:

multiSet([
   ['SECOND_KEY', 'foo'],
   ['FIRST_KEY', 123],
   ['SECOND_KEY: 'bar'],
])

If you want each key to appear at most once, then pass an object (of type Partial<localStorageType>), not an array.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm not experienced with typescript's union, so in my function I should declare it like this multiSet(pairings: Pair<localStorageType>[]) ? thanks it works awesome, but with a little problem when I typing comma , after the first element like 'FIRST_KEY', vs code doesn't show what type I should insert in the second element other than that it works as expected like in VSCode's Problems tab not give error when the second element is right, and give expected problem message when second element is wrong type
from what i see Array<Pair<localStorageType>> and Pair<localStorageType>[]) behave the same, both are works I just realized why the second element doesn't show data type suggestion, it's not like second parameter in a function that the IDE can show you the type haha, after understanding it for now it's not a problem
you right, i need to change it to an object if i want each key to appear at most once however this question is still count as a valid question and your answer too thanks for the insight, I will still upvoted and accept the answer, I wish i can double / triple / quadruple upvote it :)
0

I would define two different types. Then use union type to differenciate them when you use them (as params of a function for example)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.