#Why does explicitly defining a type for an object literal remove a circular reference?

29 messages · Page 1 of 1 (latest)

torn masonBOT
#

@leaden sonnet Here's a shortened URL of your playground link! You can remove the full link from your message.

bawdyinkslinger#0

Preview:```ts
type TestControllerPromise = Promise<void> &
typeof methods

const wait = () =>
new Promise(resolve => setTimeout(resolve, 1000))

const methods = {
click(
this: Promise<void>,
arg: string
): TestControllerPromise {
return attachMethods(
this.then(() => wait()).then(() =>
console.log("click", arg)
)
)
},
drag(
...```

leaden sonnet
#

This code errors ^

torn masonBOT
#

@leaden sonnet Here's a shortened URL of your playground link! You can remove the full link from your message.

bawdyinkslinger#0

Preview:```ts
type TestControllerPromise = Promise<void> &
typeof methods

const wait = () =>
new Promise(resolve => setTimeout(resolve, 1000))

const methods: {
click: (
this: Promise<void>,
arg: string
) => TestControllerPromise
drag: (
this: Promise<void>,
arg: string
) => TestControllerPromise
} = {
click(
this: Promise<void>,
arg:
...```

leaden sonnet
#

This code does not ^

#

all I've done is defined an explicit type on methods. It still refers to TestControllerPromise though. Why does this remove a circular reference error?

delicate lava
#

circular type definitions like that can't be done

leaden sonnet
delicate lava
#

in the second example you've broken the cycle by declaring the type of const method

#

the problem is

type TestControllerPromise = Promise<void> & typeof methods;

depends on the type of const methods

#

and const methods has properties with function type with return type of TestControllerPromise

#

so it can't infer the type of const methods because of that cycle

leaden sonnet
#

I guess I understand the error message, I don't understand why defining a type fixes the error message

delicate lava
#

but it used to be you couldn't build self-referential types like that by hand either

leaden sonnet
#

I see. I also noticed that if I make the object literal into a class, I don't think it's an error

#

Though I may be remembering that incorrectly

#

The problem with doing that is I Don't know how to copy over the Methods.

delicate lava
#

well, I can tell you how to do that, but it's a little hackish

#

before that, can you tell me why you don't just subclass promise? i.e. class TestControllerPromise extends Promise<void>?

leaden sonnet
#

I don't really have a good reason. I'm trying to mimic the api that comes from testcafe. It uses a builder pattern but most things return a promise

#

I guess one reason I can think of is that sometimes I want to return a test controller that's not a promise?

#

I don't know when that would come up. I don't even know if that would be a reason not to do what you're saying

delicate lava
leaden sonnet
#

It seems to get away with this type declaration, But I can't figure out how its implementation works

delicate lava
#

but here's how you can get the methods off of a class

torn masonBOT
#
webstrand#0

Preview:```ts
type TestControllerPromise = Promise<void> & methods;

const wait = () => new Promise((resolve) => setTimeout(resolve, 1000));

class methods {
click(this: Promise<void>, arg: string): TestControllerPromise {
return attachMethods(
this.then(() => wait()).then(() => console.log("click", arg)),
...```

leaden sonnet
#

Hm, from entries...

leaden sonnet