#Generics help

17 messages · Page 1 of 1 (latest)

shut cipher
#
type Lifecycle = "before" | "after";

type Foo<A, B> = {
    [key in Lifecycle]?: (...args: A[]) => B;
};

type Bar = Foobar<[string], void>;
type Baz = Foobar<[number, number], void>;

const example1: Bar = {
    after: (str) => { console.log(str); }
const example2: Baz = {
    after: (num1, num2) => num1 + num2
};

I'm trying to use generics so that type Baz will work like the "example" objects below, like, the object keys should stay the same but I want to be able to define before/after keys' argument types and their return. The same object keys, but different function parameters and function return.

tired gale
#
type Foo<A extends unknown[], B> = {
    [key in Lifecycle]?: (...args: A) => B;
};
river knot
#

i would stick a readonly for A just in case the more creative user passes a readonly tuple

shut cipher
shut cipher
#

Hmm... This works but it doesn't enforce return type for some reason?

#

I can still return a number even though I defined Baz to return void.

#

Also doesn't enforce argument types either, it gives me the type definition but doesn't enforce them. 😄

#

I'm assuming it's because of "unknown"?

tired gale
#

Void means “whatever the return value of the function is, you can’t use it”

#

It doesn’t forbid the function from returning something.

shut cipher
#

Okay but I can still return a string even if the return type is number.

#

In fact, it lets me define the argument types inside the before/after keys.

tired gale
#

Can you show a playground?

shut cipher
#

Sure.

#

Oh, nevermind, I think it's because I was trying this inside a declaration file's namespace.

#

When I used it in source code it errored out as I hoped.