Skip to content

Instantly share code, notes, and snippets.

@lordlycastle
Last active July 16, 2021 17:50
Show Gist options
  • Select an option

  • Save lordlycastle/4d21218a015d3520408be25a808ff7dd to your computer and use it in GitHub Desktop.

Select an option

Save lordlycastle/4d21218a015d3520408be25a808ff7dd to your computer and use it in GitHub Desktop.
Create a function that allows you to add required properties to an object one by one. This can reduce common TS pain where you do have all required properties at object instantiation time.
import { compose } from 'rambda';
class Test {
public static sayHello() {
console.log('Hello World!');
}
}
interface Test1 {
a: string
}
type Test2 = {
a: string
};
const test3: keyof Test1 = 'a';
type CheckIsRecord<T> = T extends Record<keyof T, unknown> ? T : never;
const test1: CheckIsRecord<Test1> = { a: 'hello' };
const test2: CheckIsRecord<Test2> = { a: 'hello' };
type MakeRequired<T, K extends keyof T> = {
[Prop in K]-?: T[Prop]
} & Omit<T, K>
type X = MakeRequired<{ a?: string, b?: number }, 'a' | 'b'>
const x: X = { a: 'hello', b: 42 };
//type ValueOf<T> = T[keyof T];
const a: X['a'] = x['a'];
type A = X['a'];
const b: A = 'string type';
type Values = X[keyof X] // === string | number
type M = { a?: string, b: number };
type N = { b: string, c: boolean };
type P = { c: boolean, d: number };
type Q = M & N | P & N;
function assertProp<T, K extends keyof T>(obj: T, key: K): asserts obj is MakeRequired<T, K> & T {
if (!obj[key]) {
throw new Error('Mandatory prop missing');
}
}
function addProp<T, K extends keyof T>(
obj: T,
key: K,
val: T[K]
): MakeRequired<T, K> & T {
obj[key] = val;
assertProp(obj, key);
return obj;
}
console.log({}, 'z', 'string');
function addPropCurried<T, K extends keyof T>(
key: K,
val: T[K]
): <R>(obj: R & { [x: K]: T[K] }) => MakeRequired<T, K> {
return (obj) => addProp(obj, key, val);
}
const q: Q = { c: false, b: b, d: 42 };
const addZAsString = addPropCurried<{z: string}, 'z'>('z', 'string');
const qz = addZAsString(q);
console.log(qz);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment