I'm in need of two utility types: one subset of a type with matching value types and one that only needs the keys to exist in the other type.
I came up with the following which seems ok at first glance but I can't help but wonder if I'm doing something that is already built into TS (v4.7).
Update:
The problem why I was working on this was not with the type itself but with casting. Casting { nammme: 'John' as any } as Partial<Person>
works, which I want to prevent. I need to override the type of some properties (but preferably not all).
// This works...
const fields: Partial<DbUser> = {
organizationId: FieldValue.delete() as any,
groups: FieldValue.delete() as any,
};
return getFirestore()
.collection(constants.dbCollections.users)
.doc(context.auth.uid)
.update(fields);
// This allows typos...
return getFirestore()
.collection(constants.dbCollections.users)
.doc(context.auth.uid)
.update({
organizationId: FieldValue.delete() as any,
groups: FieldValue.delete() as any,
typoooo: 1 as any,
} as Partial<DbUser>);
Code example
type Person = {
name: string;
age: number;
};
export type KeysIn<T> = {
[key in keyof Partial<T>]: any;
};
export type MustContainKeyButTypeOfKeyCanBeOverwritten<T> = unknown; // ?
// Valid: Key exists in Person
const valid1: KeysIn<Person> = {
name: 0,
};
// Valid: Key exists in Person and type matches
const valid2: Partial<Person> = {
name: '',
};
// Invalid: Key does not exist in Person
const invalid1: KeysIn<Person> = {
x: true,
};
// Invalid: Key exists in Person but type does not match
const invalid2: Partial<Person> = {
name: 0,
};
// Invalid: Key does not exist in Person
const invalid3: Partial<Person> = {
x: true,
};
// Typo with cast to any
const invalid4: KeysIn<Person> = {
namessss: '' as any,
};
const invalid5 = {
namessss: '' as any,
} as Partial<Person>; // Why is this valid?
const invalid6 = {
namessss: '' as any,
} as KeysIn<Person>; // Why is this valid? I need this to be invalid
const idealExample: MustContainKeyButTypeOfKeyCanBeOverwritten<Person> = {
name: 1 as any, // Allowed type override
aggggggge: 1, // Typo, invalid
age: '2', // Wrong type, invalid
};
Can I override only certain keys with new types while preventing typos?
Partial
does what you want out of Subset
.
export type Subset<T> = Partial<T>;
For KeysIn
I think your definition makes sense, an alternative is the following.
export type KeysIn<T> = Partial<Record<keyof T, any>>;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.