```interface DataStorePreference<K : Preference...
# getting-started
s
Copy code
interface DataStorePreference<K : PreferenceKeys<*>> {
    fun <T> getPreference(key: PreferenceKeys<T>, defaultValue: T): Flow<T>
    suspend fun <T> putPreference(key: PreferenceKeys<T>, value: T)
    suspend fun <T> removePreference(key: PreferenceKeys<T>)
    suspend fun clearAllPreference()
}
Copy code
sealed class PreferenceKeys<T>(val key: Preferences.Key<T>) {
    sealed class UserKeys<T>(key: Preferences.Key<T>) : PreferenceKeys<T>(key) {
        data object IntroScreenShown : UserKeys<Boolean>(booleanPreferencesKey("intro_screen_shown"))
        data object IsLoggedIn : UserKeys<Boolean>(booleanPreferencesKey("is_logged_in"))
    }

    sealed class DataKeys<T>(key: Preferences.Key<T>) : PreferenceKeys<T>(key) {
        data object AccessToken : DataKeys<String>(stringPreferencesKey("access_token"))
        data object ClientID : DataKeys<String>(stringPreferencesKey("client_id"))
    }
}
I have this implementation to help me create different objects of different types of datastore prefs i basically wanted to enforce type safety between different types of preferences i might have Here i have 2 i.e User and Data Now i dont want to allow userkeys in data prefs file What am i doing wrong?
Copy code
class DataStorePreferenceImpl<K : PreferenceKeys<*>> @Inject constructor(
    private val preferencesDataStore: DataStore<Preferences>
) : DataStorePreference<K> {

    override fun <T> getPreference(key: PreferenceKeys<T>, defaultValue: T): Flow<T> =
        preferencesDataStore.data.catch { exception ->
            if (exception is IOException) {
                emit(emptyPreferences())
            } else {
                throw exception
            }
        }.map { preferences ->
            preferences[key.key] ?: defaultValue
        }

    override suspend fun <T> putPreference(key: PreferenceKeys<T>, value: T) {
        preferencesDataStore.edit { preferences ->
            preferences[key.key] = value
        }
    }

    override suspend fun <T> removePreference(key: PreferenceKeys<T>) {
        preferencesDataStore.edit {
            it.remove(key.key)
        }
    }

    override suspend fun clearAllPreferences() {
        preferencesDataStore.edit { preferences ->
            preferences.clear()
        }
    }
}
I wanted to enforce type safety on type of DataStore and try and avoid unrelated data being stored in different datastore
Copy code
@Singleton
@Provides
fun provideUserPreferencesDataStore(
    @ApplicationContext context: Context,
    preferencesCoroutineScope: CoroutineScope
): DataStorePreference<PreferenceKeys.UserKeys<*>> =
    DataStorePreferenceImpl(
        PreferenceDataStoreFactory.create(
            corruptionHandler = ReplaceFileCorruptionHandler(produceNewData = { emptyPreferences() }),
            scope = preferencesCoroutineScope,
            produceFile = { context.preferencesDataStoreFile(USER) }
        )
    )

@Singleton
@Provides
fun provideDataPreferencesDataStore(
    @ApplicationContext context: Context,
    preferencesCoroutineScope: CoroutineScope
): DataStorePreference<PreferenceKeys.DataKeys<*>> =
    DataStorePreferenceImpl(
        PreferenceDataStoreFactory.create(
            corruptionHandler = ReplaceFileCorruptionHandler(produceNewData = { emptyPreferences() }),
            scope = preferencesCoroutineScope,
            produceFile = { context.preferencesDataStoreFile(DATA) }
        )
    )
This is how im injecting it