question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

4.8.2: Type serialization error with unique symbol

See original GitHub issue

Bug Report

Original issue: https://github.com/stitchesjs/stitches/issues/1078

When two types refer to the same unique symbol and they are combined via inference, exporting the inferred type results in a 4118 serialization error.

🔎 Search Terms

Unique symbol, serialized, error, 4118

🕗 Version & Regression Information

  • This changed between versions 4.7.4 and 4.8.2

⏯ Playground Link

// @filename: node_modules/@types/foo/symbols.d.ts
/** Unique symbol used to reference a property value. */
export declare const $$Sym: unique symbol;

/** Unique symbol used to reference a property value. */
export type $$Sym = typeof $$Sym;

// @filename: node_modules/@types/foo/properties.d.ts
export interface CSSProperties {
    a?: 'a';
    b?: 'b';
    c?: 'c';
}

// @filename: node_modules/@types/foo/stitches.d.ts
import type { $$Sym } from './symbols';
import type { CSSProperties } from './properties';

type ValueByPropertyName<PropertyName> = PropertyName extends keyof CSSProperties ? CSSProperties[PropertyName] : never

export type CSS<Utils = {}> =
    {
        [K in keyof Utils as K extends keyof CSSProperties ? never : K]?: Utils[K] extends (arg: infer P) => any
        ? (
            $$Sym extends keyof P
            ? (ValueByPropertyName<P[$$Sym]> | undefined)
            : never
        )
        : never
    }
    & {
        [K in keyof CSSProperties]: CSSProperties[K]
    }


export interface Stitches<Utils extends {} = {}> {
    css<
        Composers extends (string | { [name: string]: unknown })[],
        C = CSS<Utils>
    >(...composers: { [K in keyof Composers]: C }): unknown
}

export declare function createStitches<Utils extends {} = {}>(config?: { utils?: Utils }): Stitches<Utils>;

// @filename: node_modules/@types/foo/index.d.ts
import type { CSS } from './stitches';
export { createStitches } from './stitches';

import type { $$Sym } from './symbols';
import type { CSSProperties } from './properties';

export type PropertyValue<Property extends keyof CSSProperties, Config = null> = (
    Config extends null
    ? { readonly [K in $$Sym]: Property }
    : Config extends { [K: string]: any }
    ? CSS<Config['utils']>[Property]
    : never
)

// @filename: test.ts
// @showEmit: true
// @showEmittedFile: test.js
// @declaration: true
// @errors: 4118

import { createStitches } from 'foo';
import type * as Foo from 'foo';

export const { css } = createStitches({ // <- Error in 4.8.2 and above
    utils: {
        d: (value: Foo.PropertyValue<'c'>) => ({
            d: value
        }),
    }
})

const foo = css({
    c: 'c',
    d: 'c'
})

Workbench Repro

🙁 Actual behavior

Error: The type of this node cannot be serialized because its property ‘[$$Sym]’ cannot be serialized.(4118)

🙂 Expected behavior

No error.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:3
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

11reactions
testavengercommented, Sep 17, 2022

When will this issue be fixed

4reactions
jgozcommented, Sep 13, 2022

Thanks @jakebailey that looks directly related.

This is the workaround I used to solve the linked issue.

type WithPropertyValue<P> = {
  readonly [K in $$Sym]: P
}

export type PropertyValue<Property extends keyof CSSProperties, Config = null> = (
    Config extends null
    ? WithPropertyValue<Property>
    : Config extends { [K: string]: any }
    ? CSS<Config['utils']>[Property]
    : never
)

This avoids serializing the late-bound name ($$Sym) altogether because WithPropertyValue is rewritten as import('./path/to').WithPropertyValue<Property>.

If this is the only path forward, it seems like an acceptable tradeoff, especially given the complexity of the types in this library. I mostly wanted to validate that this was a deliberate change and not a regression.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Runtime Changes for Migration from .NET Framework 4.5.2 to ...
Serialization.Json.DataContractJsonSerializer fails to serialize or deserialize due to missing 'known types' has been clarified. Suggestion.
Read more >
Mockito (Mockito 4.11.0 API) - javadoc.io
Mockito mocks can be serialized / deserialized across classloaders (Since 1.10.0) ... Mocking final types, enums and final methods (Since 2.1.0)
Read more >
Why does System.Text.Json throw a `NotSupportedException ...
Your code is failing during serialization not deserialization because you are catching some inner exception and trying to serialize it with ...
Read more >
marshal - Documentation for Ruby 2.2.0
“u” represents an object with a user-defined serialization format using the _dump instance method and _load class method. Following the type byte is...
Read more >
Firebase JavaScript SDK Release Notes - Google
These typings caused errors in some projects using both Node.js and TypeScript. App Check. Fixed a bug where @firebase/app-check-types ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found