Skip to content

Instantly share code, notes, and snippets.

@tlaitinen
Created July 25, 2018 08:42
Show Gist options
  • Select an option

  • Save tlaitinen/9b179fecf20f7f577ca27a0765b51ce8 to your computer and use it in GitHub Desktop.

Select an option

Save tlaitinen/9b179fecf20f7f577ca27a0765b51ce8 to your computer and use it in GitHub Desktop.
interface SetGet<A,V> {
setValue: (o:A, v:V) => A;
getValue: (o:A) => V;
}
function f<A>(k:keyof A):SetGet<A, A[typeof k]> {
return {
setValue: (a:A, v:A[typeof k]) => Object.assign({}, a, {[k]: v}),
getValue: (a:A) => a[k]
};
}
interface B {
s: string;
n: number;
}
function f2<A>(a:A, sg:SetGet<A,string>):string {
const a2 = sg.setValue(a, 'aa');
return sg.getValue(a2);
}
const bs = f<B>('s');
const bn = f<B>('n');
const b:B = {s:'s',n:0};
f2(b, bs);
f2(b, bn);
/*
foo.ts:27:7 - error TS2345: Argument of type 'SetGet<B, string | number>' is not assignable to parameter of type 'SetGet<B, string>'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
27 f2(b, bs);
~~
foo.ts:28:7 - error TS2345: Argument of type 'SetGet<B, string | number>' is not assignable to parameter of type 'SetGet<B, string>'.
28 f2(b, bn);
~~
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment