【问题标题】:How is my BehaviorSubject<T> being typed as 'never'?我的 BehaviorSubject<T> 是如何被输入为“从不”的?
【发布时间】:2021-11-10 05:56:52
【问题描述】:

我正在使用对象内部的BehaviorSubjects 以角度构建服务文件,并在 VS Code 中收到以下错误。

'string' 类型的参数不能分配给'never' 类型的参数。

我之前以同样的方式使用过BehaviorSubjects,所以我无法弄清楚在这种情况下我做错了什么。我在服务文件中有很多事情要做,所以我将把它省略为我正在尝试设计的模式类型的单个实例。

//a set of values a user will select through an input.
export type MtSizeOptionType = '--'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'10'|'11'|
                           '12'|'13'|'14'|'15'|'16'|'17'|'18'|'19'|'20'|'21'|'22'|
                           '23'|'24'|'25'|'26'|'27'|'28'|'29'|'30'|'31'|'32'|'33'|
                           '34'|'35'|'36'|'37'|'38'|'39'|'40'|'41'|'42'|'43'|'44';


//a type for shaping one of the types of datasets I want to use.
export type MtSizeObserver = {
    params  : BehaviorSubject<MtSizeOptionType>,
    setting : BehaviorSubject<string>
};


//a type for allowing the data object to be shaped as one of these data types which I'm
//leaving out for brevity.
export type PropObserver = NumberObserver | StringObserver   | BoxSizeObserver |
                           MtSizeObserver | FontSizeObserver | LineSizeObserver;


//an interface to shape the data entries.
export interface MainObserver{  [key : string] : PropObserver;  }


//a function I import into the service file to create a string to store as a setting.
export function CreateMtSize(size: string): string { return `mt-${size}`; }



@Injectable({
  providedIn: 'root'
})
export class ResponsiveShellService {

    //the data object
    private PropertyMaster : MainObserver = {
        CrushGapWSetting: {
            params  : new BehaviorSubject<MtSizeOptionType>('--'),
            setting : new BehaviorSubject<string>('mt-1')
        },
        //all the other elements
    }

    constructor(){}

    //the function where I attempt to update the CrushGapWSetting
    public updateCrushGapW(val: MtSizeOptionType){

        const defaultSize: string = '--mt-1';

        this.PropertyMaster.CrushGapWSetting.params.next(val); //error

        if(val === '--'){
            this.PropertyMaster.CrushGapWSetting.setting.next(defaultSize);  //error
        }
        else {
            this.PropertyMaster.CrushGapWSetting.setting.next(CreateMtSize(val));  //error
        }

    }
}

updateCrushGapW() 函数中的每个 .next() 都会抛出 not assignable to parameter type of 'never' 错误,我不明白它是如何输入为 never 的。谁能看到这是怎么回事?如果您需要查看其他类型,请告诉我,我会添加它们。

【问题讨论】:

标签: angular typescript rxjs


【解决方案1】:

您还没有向我们提供NumberObserverStringObserver 等是什么。我的猜测是它们都间接指向了一个带有函数“next”的对象,但是每个“next”的参数类型是不同的类型。

这是一个更简单的示例,说明如何获取“不可分配给'never'的参数类型”。

interface NumberObserver {
  next(v:number) : void;
}

interface StringObserver {
  next(v:string) : void;
}


type PropObserver = NumberObserver | StringObserver;;

interface MainObserver { [key: string] : PropObserver; }


const PropertyMaster : MainObserver = {};

PropertyMaster.CrushGapWSettings.next("hello"); // << == Argument of type 'string' is not assignable to type 'never'

CrushGapWSettingsNumberObserverStringObserver 类型的并集。

如果不将其强制转换为特定类型,则可以对联合类型进行操作。

TypeScript 仅允许您使用该联合执行的操作,前提是该操作对联合的每个成员都有效。

他们都有一个方法next,所以你可以访问函数next。 该函数的参数是numberstring 类型的交集。 (number &amp; string) 两个基本类型的交集是never。 (number &amp; string = never)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-15
    • 2019-07-13
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多