known working examples of TS generics inferencing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function identity<T>(arg: T): T { | |
return arg; | |
} | |
const val = identity(1 as const); | |
// ^ 1 | |
// ---------------------- Works with classes too --------------------------------------------- | |
class IdentityWithMeta<T> { | |
value: T; | |
touched: boolean = false; | |
constructor(val: T) { | |
this.value = val; | |
} | |
update(val: T) { | |
this.touched = true; | |
} | |
} | |
const classVal = new IdentityWithMeta(1 as const); | |
classVal.value; | |
// ^ 1 | |
// ---------------------- Works with defaults --------------------------------------------- | |
function identityWithMeta<T = never>(arg: T): {arg: T, isTouched: boolean} { | |
return {arg, isTouched: false}; | |
} | |
const meta = identityWithMeta(1 as const); | |
meta.arg; | |
// ^ 1 | |
// ---------------------- Works with classes and defaults too --------------------------------------------- | |
class IdentityWithMetaAndDelete<T = never> { | |
value: T | null; | |
touched: boolean = false; | |
constructor(val: T) { | |
this.value = val; | |
} | |
update(val: T) { | |
this.touched = true; | |
} | |
delete() { | |
this.touched = true; | |
this.value = null; | |
} | |
} | |
const classValWithDelete = new IdentityWithMetaAndDelete(1 as const); | |
classVal.value; | |
// ^ 1 | |
// ---------------------- Works with return interface --------------------------------------------- | |
interface IdentityWithMetaInterfaceRet<T> { | |
arg: T; | |
isTouched: boolean; | |
} | |
function identityWithMetaReturnInterface<T = never>(arg: T): IdentityWithMetaInterfaceRet<T> { | |
return {arg, isTouched: false}; | |
} | |
const metaInterface = identityWithMetaReturnInterface(1 as const); | |
metaInterface.arg; | |
// ^ 1 | |
// ---------------------- Works with prop object --------------------------------------------- | |
function identityMetaProps<T = never>(arg: {value: T, isTouched: boolean}): T { | |
return arg.value; | |
} | |
const propReturn = identityMetaProps({value: 1, isTouched: false} as const); | |
propReturn; | |
// ^ 1 | |
// ---------------------- Works with prop interface --------------------------------------------- | |
interface IdentityMetaPropsInterfaceProp<T> { | |
value: T; | |
isTouched: boolean; | |
} | |
function identityMetaPropsInterface<T = never>(arg: IdentityMetaPropsInterfaceProp<T>): T { | |
return arg.value; | |
} | |
const propInterfaceReturn = identityMetaPropsInterface({value: 1, isTouched: false} as const); | |
propInterfaceReturn; | |
// ^ 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------------------- Doesn't work --------------------------------------------- | |
interface Test<T = unknown, O = unknown> { | |
test: T, | |
other: O | |
} | |
function getTest(args: Test) { | |
return args; | |
} | |
const {test, other } = getTest({ | |
test: "test", | |
other: "other" | |
} as const) | |
// ---------------------- Does work --------------------------------------------- | |
interface Two<T = unknown, O = unknown> { | |
one: T, | |
two: O | |
} | |
function getAnotherTest<T, O>(args: Two<T, O>) { | |
return args; | |
} | |
const {one, two } = getAnotherTest({ | |
one: "test", | |
two: "other" | |
} as const) | |
// ---------------------- Does work --------------------------------------------- | |
interface Three<T = unknown, O = unknown> { | |
three: T, | |
four: O | |
} | |
function getOneMoreTest<T, O = unknown>(args: Three<T, O>) { | |
return args; | |
} | |
const {three, four } = getOneMoreTest({ | |
three: "test", | |
four: "other" | |
} as const) | |
// ---------------------- Does work --------------------------------------------- | |
interface Four<T = unknown, O = unknown> { | |
five: T, | |
six: O | |
} | |
class FourTest<T, O> { | |
constructor(public opts: Four<T, O>) { | |
} | |
returnOpts() { | |
return this.opts; | |
} | |
} | |
const obj = new FourTest({ | |
five: "test", | |
six: "other" | |
} as const) | |
const {five, six } = obj.returnOpts(); | |
// ---------------------- Does work --------------------------------------------- | |
interface Five<T = unknown, O = unknown> { | |
seven: T, | |
eight: O | |
} | |
class FiveTest<T, O = unknown> { | |
constructor(public opts: Five<T, O>) { | |
} | |
returnOpts() { | |
return this.opts; | |
} | |
} | |
const otherObj = new FiveTest({ | |
seven: "test", | |
eight: "other" | |
} as const) | |
const {seven, eight } = otherObj.returnOpts(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------------------- Does work --------------------------------------------- | |
interface Five<T = unknown, O = unknown> { | |
seven: T, | |
eight: O | |
nine: O | |
} | |
class FiveTest<T, O = unknown> { | |
constructor(public opts: Five<T, O>) { | |
} | |
returnOpts() { | |
return this.opts; | |
} | |
} | |
const otherObj = new FiveTest({ | |
seven: "test", | |
eight: "other", | |
nine: 1 | |
// ^ Complains about not being "other", since `eight` comes first | |
} as const) | |
const {seven, eight, nine } = otherObj.returnOpts(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment