Typescript 如何使用控制流缩小变量类型?

Typescript 如何使用控制流缩小变量类型?,typescript,Typescript,读完之后,我试图找出如何通过控制流缩小变量范围。例如: type T1 = { a?: { b: string } } const t1: T1 = {} t1.a.b // error, possibly undefined t1.a = { b: "foo" } t1.a.b // works now, TS recognizes, that property a now exists 具体的情况是,我目前正在努力: const t1: T1 = {} t1.a = {

读完之后,我试图找出如何通过控制流缩小变量范围。例如:

type T1 = {
  a?: {
    b: string
  }
}

const t1: T1 = {}

t1.a.b // error, possibly undefined
t1.a = { b: "foo" }
t1.a.b // works now, TS recognizes, that property a now exists
具体的情况是,我目前正在努力:

const t1: T1 = {}
t1.a = { b: "foo" }

function foo(t: T1) {
  t.a = undefined
}

foo(t1) // function foo mutates prop "a" inside to be undefined again
// t1.a = undefined  ; this would correctly emit error

console.log(t1.a.b) // ... "a" is still regarded as defined here and TS compiles successfully :/
// This will be a runtime error.
我希望TS能够认识到,
foo
处理可变值
t1
t1
中的属性没有
readonly
标志)
foo
可能已经更改了值(在本例中确实如此),因此编译器应该重置
t1
的所有先前缩小类型,并在
console.log(t1.a.b)
中再次报告
a


我现在的问题是:这个控制流机制有多复杂?对于上面的例子,它遵循什么规则?这是你的电话号码。谢谢大家!

您可能希望每次检查
a
是否有属性
b

let c = ('b' in t1.a)? t1.a.b : undefined;

这里有一个链接,可以了解有关操作员的更多信息

您可能希望每次检查
a
是否有属性
b

let c = ('b' in t1.a)? t1.a.b : undefined;

这里有一个链接,可以了解有关运算符函数的更多信息
foo
是典型的副作用full函数,它获取一个参数,对其进行更改,然后返回
void
。TS确实按照自上而下的流程跟踪代码,因此它会检查
foo
是否获得了正确的参数,但不会控制它对它做了什么以及它如何影响上面的范围。通知scope我们所做的事情的唯一方法是返回值。目前关于
foo
的外部作用域的唯一信息是它想要
T1
作为参数,并且它不返回任何内容

需要指出的是,隐式参数更改的这种实现也是一种反模式,因为
foo
是一个非常不安全的函数,它不会在类型级别上通知它所做的事情(它没有返回)。我们可以通过返回更改的值来通知top scope有关更改的信息。考虑如下:

let t1: T1 = {} // change to let
t1.a = { b: "foo" }

function foo(t: T1) {
    t.a = undefined
    return t; // return what was changed
}

t1 = foo(t1) // function return mutated value
console.log(t1.a.b) // error as a is undefined

通过这种方式,TS能够推断
foo
的返回及其对外部范围的影响


更好的方法是使
foo
成为一个纯函数(是的,这只是一个观点):


函数
foo
是典型的副作用full函数,它获取一个参数,对其进行更改,然后返回
void
。TS确实按照自上而下的流程跟踪代码,因此它会检查
foo
是否获得了正确的参数,但不会控制它对它做了什么以及它如何影响上面的范围。通知scope我们所做的事情的唯一方法是返回值。目前关于
foo
的外部作用域的唯一信息是它想要
T1
作为参数,并且它不返回任何内容

需要指出的是,隐式参数更改的这种实现也是一种反模式,因为
foo
是一个非常不安全的函数,它不会在类型级别上通知它所做的事情(它没有返回)。我们可以通过返回更改的值来通知top scope有关更改的信息。考虑如下:

let t1: T1 = {} // change to let
t1.a = { b: "foo" }

function foo(t: T1) {
    t.a = undefined
    return t; // return what was changed
}

t1 = foo(t1) // function return mutated value
console.log(t1.a.b) // error as a is undefined

通过这种方式,TS能够推断
foo
的返回及其对外部范围的影响


更好的方法是使
foo
成为一个纯函数(是的,这只是一个观点):