#Narrow property type of implementation of custom type

53 messages · Page 1 of 1 (latest)

dreamy lava
#

I'm having some issues with type narrowing values of an implementation of a type. Something like```ts
type Adapter = {
foo: any
}

const bar: Adapter = {
foo: 123
} as const;

console.log(bar.foo)
// ^? -> typed as any but want it to be number


Full code is on TS-playground, with `TODO`s for where there's this issue (towards the bottom): https://tsplay.dev/Nry71w
knotty jungle
#
const bar = {
    foo: 123
} satisfies Adapter
#

Can throw in as const as well if you want it.

dreamy lava
#

Hmm, interesting

#

I've not seen satisfies before, will give that a go

#

@knotty jungle That seems to work for one case, but not here:ts const adapters: Record<EventSource, satisfies Adapter> = { JIRA: jiraAdapter, } as const;

#

I guess const adapters = {...} as const satisfies Record<...>?

knotty jungle
#

Sure.

dreamy lava
knotty jungle
#

That error doesn't look related.

rugged stormBOT
#
type Adapter = {
    foo: any
}

const bar = {
    key: {
        foo: 123,
    },
} as const satisfies Record<string, Adapter>

bar
//^? - const bar: {
//    readonly key: {
//        readonly foo: 123;
//    };
//}
dreamy lava
#

Even removing the satisfies Record<string, Adapter> I've still got it 🤔

knotty jungle
#

You have recursive dependency going on.

#

jiraAdapter -> applyMappings -> SourceToPayload -> Adapters -> adapters -> jiraAdapter.

dreamy lava
#

Hmm

#

Yes, I see

#

How do I get around this?

knotty jungle
#

Untangle the circular dependency somehow.

dreamy lava
#

I'm... not sure I can

knotty jungle
#

You just need to cut the circular dependency loop somewhere.

dreamy lava
#

Yeah, but this chain is accurate

#

I'm not sure how to cut it

knotty jungle
#

Well I'm not going to read all of that code, but look at any point in that loop and see if one really needs to depend on the other.

#

jiraAdapter -> applyMappings seems like a potential place to cut, or adapters -> jiraAdapter.

dreamy lava
#

What exactly do you mean by "cut" in this context?

dreamy lava
knotty jungle
#

Sure, but at the point of calling applyMappings, do you really need to know the exact type of adapters?

dreamy lava
#

Hmm

#

At the point of calling applyMappings, no, but there's other parts of the code (not included in the paste, that are executed beforehand) where I need to know the exact type of adapters

dreamy lava
# knotty jungle Sure, but at the point of calling `applyMappings`, do you really need to know th...

The flow of the entire program is something like:```ts
// Define different adapters

// Join adapters into an object of {source: adapterForSource}

// Recieve input payload

// Determine source of payload

// Get adapter for this source (requires knowing type of adapters)

/* now never need to know exact type of adapters */

// If adapter.shouldBeTransformed(payload) is true, then call adapter.remap(payload, ...)

knotty jungle
#

You'd have to figure it out yourself.

rugged stormBOT
#
nonspicyburrito#0

Preview:```ts
type Box = {
color: string
getSimilarBoxes(garage: Garage): Box[]
}

const redBox = {
color: "red",
getSimilarBoxes(garage: Garage) {
return garage.filter(
box => box.color === this.color
)
},
}

const garage = [redBox]

type Garage = typeof garage
...```

knotty jungle
#

Here's an example of circular dependency where redBox -> garage -> redBox

#

You can easily break this chain in either places.

#
- const redBox = {
+ const redBox: Box = {
- type Garage = typeof garage
+ type Garage = Box[]
#

The first solution breaks garage's reliance on knowing what type redBox is, by explicitly giving redBox a type (Box)
The second solution breaks readBox's reliance on knowing what Garage is, by explicitly giving Garage a type (Box[])

dreamy lava
#

Hmm, interesting

#

Here you're fixing it by explicitly giving types. Is that always how "cutting" works?

#

I mean, I can see two places I can fix this issue (giving jiraAdapter or adapters an explicit type), but it means I go back to my original issue where values don't get narrowed

#

Everything else in the chain already has an explicit type 😩

dreamy lava
knotty jungle
#

Eh

#

I mean why does jiraAdapter's type need to depend on anything?

dreamy lava
#

I want to enforce all of the keys being there... although... I guess that would be done when I put it in adapters??

knotty jungle
#

In your comment for jiraAdapter.remap:

// TODO: Return type should override that of Adapter.remap i.e. should be RemappedJiraIssueEventSchema
#

So you already know that function should return RemappedJiraIssueEventSchema.

#

There's no need to use the type of applyMappings and cause a circular dependency.

dreamy lava
#

Hmm, yeah

#

Now that I've got satisfies that shouldn't be an issue

dreamy lava
#

Just need to fix something else

#

Yeah, I think it should be working now, thank you @knotty jungle!