Typescript 使用同一接口为不同的类实现编写类型脚本。检查其实例的字段

Typescript 使用同一接口为不同的类实现编写类型脚本。检查其实例的字段,typescript,oop,types,interface,monads,Typescript,Oop,Types,Interface,Monads,尝试为我的应用程序中的某些业务逻辑实现两个类,下面是一些伪代码(我使用object和string类型,但主要思想是为每个逻辑指定每个类型) 有一些接口和类声明 interface IResult<T, E> { result: T; err: E; } class Fail<E> implements IResult<null, E> { private readonly _error: E; constructor(err

尝试为我的应用程序中的某些业务逻辑实现两个类,下面是一些伪代码(我使用
object
string
类型,但主要思想是为每个逻辑指定每个类型)

有一些接口和类声明

interface IResult<T, E> {
    result: T;
    err: E;
}

class Fail<E> implements IResult<null, E> {
    private readonly _error: E;

    constructor(error: E) {
        this._error = error;
    }

    get err(): E {
        return this._error;
    }

    get result(): null {
        return null;
    }
}

class Success<T> implements IResult<T, null> {
    private readonly _result: T;

    constructor(result: T) {
        this._result = result;
    }

    get err() {
        return null;
    }

    get result(): T {
        return this._result;
    }
}
并为其使用接口

interface IDetailsFactory {
    make(): Result<object, string>;
}
我可以这样使用它:

const detailsFactory = new DetailsFactory('1');
const {result, err} = detailsFactory.make();
这里我在
result
字段中收到预期对象,在
err
字段中收到
null
,但当我尝试检查

if (!err) {
    console.log(result.name);
}
我收到TS错误
错误:(96,14)TS2531:对象可能为“null”。
当然我可以检查
结果
而不是
!呃
但它并没有这么漂亮,我想尽早退出函数


所以问题是:如果我没有任何错误,
(!err=true)
相信我并从
结果
字段获取数据,我如何告诉TS?当
error=null
时,使其不再认为
result
字段可能是
null
,您可以使用一个有区别的并集来让编译器按照预期缩小类型。不幸的是,TS目前无法基于另一个变量缩小一个变量的范围,您只能缩小单个变量的范围

您还需要一些额外的泛型来转发实际的返回类型

type DetailsFactoryResult = 
     | { type: '1', name: string }
     | { type: '2', name: string }
     | { type: '3', name: string }

class DetailsFactory implements IDetailsFactory<DetailsFactoryResult> {
    // ...    
    public make(): Result<DetailsFactoryResult, string> {
        // ...
    }
}

const detailsFactory = new DetailsFactory("1");
const r = detailsFactory.make();

if (r.err == null) {
    console.log(r.result.name);
}
类型详细信息FactoryResult=
|{类型:'1',名称:string}
|{类型:'2',名称:string}
|{类型:'3',名称:string}
类DetailsFactory实现IDetailsFactory{
// ...    
public make():结果{
// ...
}
}
const detailsFactory=新的detailsFactory(“1”);
const r=detailsFactory.make();
if(r.err==null){
console.log(r.result.name);
}

您可以使用一个有区别的并集,让编译器按照预期缩小类型。不幸的是,TS目前无法基于另一个变量缩小一个变量的范围,您只能缩小单个变量的范围

您还需要一些额外的泛型来转发实际的返回类型

type DetailsFactoryResult = 
     | { type: '1', name: string }
     | { type: '2', name: string }
     | { type: '3', name: string }

class DetailsFactory implements IDetailsFactory<DetailsFactoryResult> {
    // ...    
    public make(): Result<DetailsFactoryResult, string> {
        // ...
    }
}

const detailsFactory = new DetailsFactory("1");
const r = detailsFactory.make();

if (r.err == null) {
    console.log(r.result.name);
}
类型详细信息FactoryResult=
|{类型:'1',名称:string}
|{类型:'2',名称:string}
|{类型:'3',名称:string}
类DetailsFactory实现IDetailsFactory{
// ...    
public make():结果{
// ...
}
}
const detailsFactory=新的detailsFactory(“1”);
const r=detailsFactory.make();
if(r.err==null){
console.log(r.result.name);
}

也许非空断言运算符可以帮助您:

if (!err) {
    console.log(result!.name);
}

也许非空断言运算符可以帮助您:

if (!err) {
    console.log(result!.name);
}

此外,我还可以将检查结果的功能添加到接口中,并使用类型检查来实现它,例如

interface IResult<T, E> {
    result: T;
    err: E;
    isOk(): boolean;
}

但我仍然在寻找一个更优雅的解决方案,通过解构和简单的
获取数据!err
检查与我上面的问题类似

此外,我还可以将检查结果的函数添加到接口中,并使用类型检查来实现它,例如

interface IResult<T, E> {
    result: T;
    err: E;
    isOk(): boolean;
}

但我仍然在寻找一个更优雅的解决方案,通过解构和简单的
获取数据!err
像我上面的问题一样检查

谢谢,是的,它可以工作,我想为业务逻辑响应制作一些类似API的东西,在这种情况下,用户应该知道他需要将strict检查为null,并创建额外的泛型。。。可能还有另一种方法可以实现这样的功能…谢谢,是的,它可以工作,我想为业务逻辑响应制作一些类似API的东西,在这种情况下,用户应该知道他需要将strict检查为null并创建额外的泛型。。。也许有另一种方式来实现这样的功能…谢谢,非常快速和简单,但可能我们只能修改背面?(接口和类),因为使用它的人可能不知道
谢谢,非常快速和简单,但可能我们只能修改背面?(接口和类),因为使用它的人可能不知道

const detailsFactory = new DetailsFactory('1');
const data = detailsFactory.make();

if (data.isOk()) {
    console.log(data.result.name);
}