在typescript函数返回值中保留类型信息

在typescript函数返回值中保留类型信息,typescript,Typescript,我很好奇如何让下面的内容在typescript中工作tempA将x.a复制到x.temp并返回它,tempB对x.b执行相同的操作。现在,无论出于何种原因,调用tempA都会使编译器忘记x上有一个b字段。有没有办法克服这个问题?或者是否存在跟踪此模式的github问题/它将以什么功能名称归档 let tempA = (x: { a: number; temp?: number}) => { x.temp = x.a; return x; } let tempB = (x:

我很好奇如何让下面的内容在typescript中工作
tempA
将x.a复制到x.temp并返回它,
tempB
对x.b执行相同的操作。现在,无论出于何种原因,调用
tempA
都会使编译器忘记
x
上有一个
b
字段。有没有办法克服这个问题?或者是否存在跟踪此模式的github问题/它将以什么功能名称归档

let tempA = (x: { a: number; temp?: number}) => {
    x.temp = x.a;
    return x;
}

let tempB = (x: { b: number; temp?: number}) => {
    x.temp = x.b
    return x;
}

let x = { a: 4, b: 3 };
let y = tempA(x);
let z = tempB(y); // Can't! y.b does not exist (even though it does)
此处,x具有以下(推断)类型签名:

设x:{a:number,b:number}={a:4,b:3}
在此之后,将其传递到方法
tempA
,该方法具有以下推断类型签名:

(x: { a: number; temp?: number }) => { a: number; temp?: number }
现在你看到问题了。当你写作时

let y: { a: number; temp?: number } = tempA(x);
显然“b”不见了。这不是一个bug或缺少的功能。考虑以下情况:

let y = tempA({ a: 4 });
// Suppress compiler warnings
// @ts-ignore
let z: { b: number; temp?: number} = tempB(y) 
// z.b = undefined, violates type constraints
要解决您的问题,您需要从根本上更改您的类型签名

// Guarantee that any 'x' passed to tempA will have a 'b' property
let tempA = (x: { a: number; b: number; temp?: number}) => {
    x.temp = x.a;
    return x;
}

let tempB = (x: { b: number; temp?: number}) => {
    x.temp = x.b
    return x;
}

let x = { a: 4, b: 3 };
let y = tempA(x);
let z = tempB(y); // Works :D

由于
x
的参数类型声明为
{a:number;temp?:number}
,并且函数返回
x
,因此返回类型推断为
{a:number,temp?:number}
。因此,这是
y
的类型,因此Typescript不知道
y
有一个名为
b
的属性

您可以通过将函数设置为泛型来解决此问题,因此它保证返回与其参数相同类型的内容:

函数tempA(x:T):T{
x、 温度=x.a;
返回x;
}
这对于您的示例代码来说已经足够好了,但并没有尽可能严格;返回类型表明该对象可能没有
temp
属性,而实际上我们可以保证它确实有此属性。我们可以使用交叉口
编写更严格的返回类型;这是一个有点混乱,所以你可能会或可能不喜欢它取决于你的要求

函数tempA(x:T):T&{temp:number}
{
x、 温度=x.a;
返回x作为T&{temp:number};
}