Skip to content

property circularly references on destructing objects but working properly without destructing #40279

Closed

Description

@tianzhich

TypeScript Version: v4.1.0-dev.20200826 (Nightly)

Search Terms: Type of property x circularly references itself in mapped type xx.

Code

type Extract<Root extends Record<string, any>> = {
    [key in keyof Root]: Root[key]
}

type Effects<T> = (p: Extract<T>) => void

export const create: <Root extends Record<string, any>>() => <
    E extends Effects<Root>,
    S extends Record<string, any>
    >(mo: {
        state?: S;
        effects?: E
    }) => {
        state: S;
        effects: E
    } = () => (p): any => p

interface Root {
    foo: typeof foo
}

const foo = create<Root>()({
    state: {
        bar: 1
    },
    // effects: (dispatch) => {
    //     // worked without destructing dispatch
    //     console.log(dispatch.foo.state.bar);
    // },
    effects: ({ foo }) => {
        // failed with destructing
        console.log(foo.state.bar);
    },
})

Expected behavior:
no errors with dispatch destructed.

Actual behavior:
errors occurred when destructing dispatch, but no errors while using it directly.

Playground Link:
https://www.typescriptlang.org/play?ts=4.1.0-dev.20200826&ssl=33&ssc=7&pln=30&pc=5#code/C4TwDgpgBAogHsATgQwMbADwCUD2PhQQIQB2AJgM5RYSo6JkYVICWJA5gDRTIkgB8-KAF4oAbwBQUaVADaAawggobKIpA4AZtTzAAugC4d+BUr0SAvhImhIsTZtrAKGACpDRACjBH4SNJjuAJQiQgBuOCxk1kRg9AR0JMxQqIgQyMAQRti6hMTkVDR0DEysHNy8AvyeIcJCGFIyMHmZBfaO6C64+PycjdIAyi2klNS09IzMiGxcPHz8-VDVALY4RpIym1DMGRAA-EYDANyLmxAOThQHsIsWtUIbW9I7mYcnT9LnHc6+tyJQNVCALAQSMlSBYGsbEyiE0aGg3QIj2kmjwRlsEC0UFROEs1kSyRx-1S6UyOR6NU8yO2wF261OMgARshEEYAIy3PqbAD03MIF06Rk8ZBYFDAGVQAAt7uJFrytvKAO70RRkKCKljASU4ACuBDIECmOvQMygIrFEslcr5mwJOAANhAAHT2nDsYWi8XAKVOnFOl7O5mIILvGTyixcmRfS5CsTYvBQO5A6k8vlwliOtUarVmw1IY3AGYM6R2x0ut2eP0Bp1BkOcyxBIA

Related Issues:
#37597
#35546

Activity

  1. tianzhich commented on Aug 27, 2020

    @tianzhich
    Author

    image

    When using foo directly, not from param. This error trigged in v3.8.3 and its previous versions. But after this like v3.9.2, it was fixed.

    image

    So I think there should no cycle reference errors when referencing the foo inside its initializer no matter from itself or function params.

  2. tianzhich commented on Sep 4, 2020

    @tianzhich
    Author

    BTW, destructing inside the function also works. Are there any differences? In my opinion, they are the same thing.

    const foo = create<Root>()({
        state: {
            bar: 1
        },
        // effects: (dispatch) => {
        //     // worked without destructing dispatch
        //     console.log(dispatch.foo.state.bar);
        // },
        // effects: ({ foo }) => {
        //     // failed with destructing
        //     console.log(foo.state.bar);
        // },
        effects: (dispatch) => {
            // it also worked while destructing inside the function, any difference here?
            const { foo } = dispatch;
            console.log(foo.state.bar);
        },
    })
  3. RyanCavanaugh commented on Sep 9, 2020

    @RyanCavanaugh
    Member

    These are different constructs and have different implications on type inference; in the destructuring case a circularity is in fact occurring

  4. semoal commented on Sep 9, 2020

    @semoal

    These are different constructs and have different implications on type inference; in the destructuring case a circularity is in fact occurring

    So, isnt there any "workaround" to handle this?

  5. tianzhich commented on Sep 10, 2020

    @tianzhich
    Author

    These are different constructs and have different implications on type inference; in the destructuring case a circularity is in fact occurring

    I do not understand well. But destructing param immediately or inside the function both worked with pure js. Is any workaround here?

  6. typescript-bot commented on Sep 12, 2020

    @typescript-bot
    Contributor

    This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  7. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions