我正在检查RxJS api文档。在理解上面写的怪异语法时,我总是会遇到问题,例如以下示例:
<ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
<ng-container *ngIf="column === 'select'; else notSelect">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
<ng-template #notSelect>
<th mat-header-cell *matHeaderCellDef> {{column}}</th>
<td mat-cell *matCellDef="let element"> {{element[column]}} </td>
</ng-template>
</ng-container>
我想了解这种语法,然后自己编写。
因此,如果有人解释上面示例中的情况,将为您提供很大的帮助。
答案 0 :(得分:6)
function combineLatest<O extends ObservableInput<any>, R>(...observables: (O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike)[]): Observable<R>
让我们分解一下。
好的,那是一个功能
function combineLatest(args): Result
,它带有一些参数并返回类型为Result
的结果
但这也是一种特殊的函数,称为generic函数。 泛型的目的是在成员之间提供有意义的类型约束。
function combineLatest<T>(args): Result
/\
now it's a generic function
这里的T
是一个 type变量,它使我们能够捕获用户提供的类型,以便以后可以使用该信息。例如,我们可以使用T
作为返回类型:
function combineLatest<T>(args): T
以便进行以下调用:
combineLatest<string>(someParams) // returns `string`
由于我们将string
显式设置为T
,因此将得到类型为string
的结果。
我们还可以将T
类型的变量用于该函数的任何参数。
function combineLatest<T>(arg: T): T
现在我们可以使用 type参数推断:
combineLatest('someStr') // returns `string`
也就是说,我们告诉编译器根据传递的参数类型为我们自动设置T
的值。我们传递了string
,以便string
。
我们可以根据需要使用任意多个类型变量。我们也可以随便叫他们。
function combineLatest<Type1, Type2, ...>(...)
泛型很棒,有时候我们想用传入的参数来做一些动作:
function combineLatest<T>(arg: T): T {
arg.name = arg.name.toLowerCase(); // Property 'name' does not exist on type 'T'
return arg;
}
如您所见,编译器无法理解哪种类型的arg
。为了解决这个问题,我们可以借助T
运算符来表示对extends
类型变量的约束:
interface ItemWithName {
name: string;
}
function combineLatest<T extends ItemWithName>(arg: T): T {
arg.name = arg.name.toLowerCase();
return arg;
}
现在,编译器知道arg具有name
的{{1}}属性。
现在让我们回到我们的初始声明:
string
我们可以在这里看到此函数使用两个类型变量:
combineLatest<O extends ObservableInput<any>, R>(...): Observable<R>
类型变量,表示可观察。限制为O
ObservableInput<any>
代表结果 R
函数的结果应为combineLatest
类型的Observable
。例如,我们可以通过调用以下函数来强制该类型:
R
现在让我们看一下该函数可以采用的参数:
combineLatest<any, MyClass>(...) // returns Observable<MyClass>
我们可以在此处看到rest parameters运算符。让我们简化上面的表达式,以便我们想象像这样的东西:
...observables: (O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike)[]
这意味着...observables: CombinedType[]
函数可以接受零个或多个参数,这些参数随后将被收集到一个变量combineLatest
中。
observables
那么此参数的类型是什么
combineLatest(); // without parameters
combineLatest(obs1); // one parameter
combineLatest(obs1, obs2, ..etc) // many parameters
可以是:
CombinedType
O | ((...values: ObservedValueOf<O>[]) => R) | SchedulerLike
类型变量的类型,该变量被限制为我们前面讨论的O
类型
或,它可以是函数ObservableInput<any>
,该函数接受零个或多个类型为(...values: ObservedValueOf<O>[]) => R
的参数,并返回类型为ObservedValueOf<O>
的变量类型。请注意,此返回类型可用于推断R
函数的返回类型。
或,它可以是combineLatest
界面的类型。
我认为,如果将TypeScript类型声明分成小块,那么理解TypeScript类型声明应该没有任何问题。