说我想创建一个import 'dart:async';
import 'package:flutter/material.dart';
class OtpTimer extends StatefulWidget {
@override
_OtpTimerState createState() => _OtpTimerState();
}
class _OtpTimerState extends State<OtpTimer> {
final interval = const Duration(seconds: 1);
final int timerMaxSeconds = 60;
int currentSeconds = 0;
String get timerText =>
'${((timerMaxSeconds - currentSeconds) ~/ 60).toString().padLeft(2, '0')}: ${((timerMaxSeconds - currentSeconds) % 60).toString().padLeft(2, '0')}';
startTimeout([int milliseconds]) {
var duration = interval;
Timer.periodic(duration, (timer) {
setState(() {
print(timer.tick);
currentSeconds = timer.tick;
if (timer.tick >= timerMaxSeconds) timer.cancel();
});
});
}
@override
void initState() {
startTimeout();
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.timer),
SizedBox(
width: 5,
),
Text(timerText)
],
);
}
}
函数:
zip
当所有数组都拥有相同类型的元素时,为了进行类型定义,请定义此函数:
function zip(arrays){
// assume more than 1 array is given and all arrays
// share the same length
const len = arrays[0].length;
const toReturn = new Array(len);
for (let i = 0; i < len; i++){
toReturn[i] = arrays.map(array=>array[i]);
}
return toReturn;
}
console.log(zip([
[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12],
]));
/*
Output:
(3) [Array(4), Array(4), Array(4)]
0: (4) [1, 4, 7, 10]
1: (4) [2, 5, 8, 11]
2: (4) [3, 6, 9, 12]
*/
但是,当数组具有不同类型的元素时,我对于如何使用泛型类型完成类型定义感到困惑。
function zip<T>(arrays: T[][]): T[][]{/* codes omited here */}
我想要的是
const zipedResult = zip([[1,2,3],[true,false,true],['a','b','c']]);
// error raises: Type 'false' is not assignable to type 'number'.(2322)
可以自动推断为 [[1,2,3],[true,false,true],['a','b','c']]
,而无需编写(number|boolean|string)[][]
甚至
推断为as (number|boolean|string)[][]
,结果[number[],boolean[],string[]]
推断为zip
我应该如何正确键入定义[number, boolean, string][]
来实现这些功能?
答案 0 :(得分:0)
我能看到的唯一方法是为您要处理的每个数组大小定义一个不同的zip
函数(因为我们需要能够准确地说出什么位于压缩结果的每个部分):
const zip3 = <T, U, V>(arrays: [T[], U[], V[]]): [T, U, V][] => {
const len = arrays[0].length;
const toReturn: [T, U, V][] = new Array(len);
for (let i = 0; i < len; i++){
toReturn[i] = [arrays[0][i], arrays[1][i], arrays[2][i]];
}
return toReturn;
};
const result = zip3([
[1,2,3],
[true, false, true],
[7,8,9],
]);
console.log(result);
希望有人可以进来并展示出一种更好的方法来执行此操作,而不必根据要压缩的数组数来重新定义函数;
答案 1 :(得分:0)
最常见的解决方案是:
declare type UnionTypes = number[] | string[] | boolean[];
function zip(arrays: UnionTypes[]): UnionTypes[]
答案 2 :(得分:0)
我相信这是您发现TS并发症没有用的少数情况之一。我只能考虑将类型放宽到any
并在必要时进行手动类型检查。
function zip(arrays: any[][]): any[][]{
// assume more than 1 array is given and all arrays
// share the same length
const len = arrays[0].length;
const toReturn = new Array(len);
for (let i = 0; i < len; i++){
toReturn[i] = arrays.map(array => array[i]);
}
return toReturn;
}
const zipedResult = zip([[1,2,3],[true,false,true],['a','b','c']]);
console.log(zipedResult); // [[1, true, "a"], [2, false, "b"], [3, true, "c" ]]