gpt4 book ai didi

带有 Symbol.observable ponyfill 的 TypeScript 可观察对象

转载 作者:行者123 更新时间:2023-12-05 06:17:07 26 4
gpt4 key购买 nike

我正在尝试键入一个可观察的对象并使用自定义 Symbol.observable ponyfill(类似于 system-observable ponyfill ;代码如下所示),但我想不出一种方法来做到这一点。

我试过使用 typeof $$observable为 key 并尝试制作Symbol.observable一个unique symbol ,但这些都不起作用。我不得不求助于转换对象,但这种方法的问题是我必须转换整个对象(下面未显示),这使得捕获其他类型错误变得更加困难,因为对象中的其他属性正在输入错误。我也不能只做 ReturnType<typeof makeObservableContainer>因为我想在一个单独的接口(interface)中定义它,而不必依赖于函数。

或者,我有兴趣知道是否有一种方法可以将其转换到比转换整个对象更细粒度的级别(如果事实证明不转换是不可能的)。

我提供了一个 playground 链接。任何帮助将不胜感激。

第一次尝试(没有类型转换)

错误信息

Property '[Symbol.observable]' is missing in type '{ [x: string]: () => { [x: string]: ((observer: Observer) => { unsubscribe(): void; }) | (() => { [x: string]: ((observer: Observer) => { unsubscribe(): void; }) | ...; subscribe(observer: Observer): { ...; }; }); subscribe(observer: Observer): { ...; }; }; }' but required in type 'Container'.(2741)

代码

// system-observable.ts
declare global {
interface SymbolConstructor {
readonly observable: symbol
}
}

const $$observable = /* #__PURE__ */ (() =>
(typeof Symbol === 'function' && Symbol.observable) || '@@observable')()

export default $$observable

// observer-creator.ts
interface Observer {
next(): void;
}

interface Observable {
subscribe: (observer: Observer) => { unsubscribe(): void };
[Symbol.observable](): Observable;
}

interface Container {
// How do I type this?
[Symbol.observable](): Observable;
}

function makeObservableContainer(): Container {
// error here because this is not assignable to `Container`
return {
[$$observable]() {
return {
subscribe(observer: Observer) {
// TODO
return {
unsubscribe() {
// TODO
}
}
},
[$$observable]() { return this }
}
},

// other properties that should conform to `Container` interface
}
}

Playground 链接: Provided


第二次尝试(独特的符号和一点类型转换)

错误

Type '() => { subscribe(observer: Observer): { unsubscribe(): void; }; observable: Observable; }' is not assignable to type '() => Observable'. Property '[Symbol.observable]' is missing in type '{ subscribe(observer: Observer): { unsubscribe(): void; }; observable: Observable; }' but required in type 'Observable'.(2322)

代码

// system-observable.ts
declare global {
interface SymbolConstructor {
readonly observable: unique symbol
}
}

const $$observable: SymbolConstructor['observable'] = /* #__PURE__ */ (() =>
(typeof Symbol === 'function' && Symbol.observable) || '@@observable')() as SymbolConstructor['observable']

export default $$observable

// observer-creator.ts
interface Observer {
next(): void;
}

interface Observable {
subscribe: (observer: Observer) => { unsubscribe(): void };
[Symbol.observable](): Observable;
}

interface Container {
// How do I type this?
[Symbol.observable](): Observable;
}

function makeObservableContainer(): Container {
// error here because this is not assignable to `Container`
return {
[$$observable]() {
return {
subscribe(observer: Observer) {
// TODO
return {
unsubscribe() {
// TODO
}
}
},
[$$observable]() { return this }
}
},

// other properties that should conform to `Container` interface
}
}

Playground 链接: Provided

最佳答案

如果将 "@@observable" 字符串转换为 any,则可以将 $$observable 作为唯一符号键入,这将让您将其用作接口(interface)的 key :

const $$observable: unique symbol = /* #__PURE__ */ (() =>
(typeof Symbol === 'function' && Symbol.observable) || ('@@observable' as any))();

export default $$observable

// observer-creator.ts
interface Observer {
next(): void;
}

interface Observable {
subscribe: (observer: Observer) => { unsubscribe(): void };
[$$observable](): Observable;
}

interface Container {
[$$observable](): Observable;
}

关于带有 Symbol.observable ponyfill 的 TypeScript 可观察对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61787314/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com