xcatliu / typescript-tutorial

TypeScript 入门教程
https://ts.xcatliu.com
10.44k stars 1.33k forks source link

函数的类型 #158

Open xcatliu opened 4 years ago

xcatliu commented 4 years ago

https://ts.xcatliu.com/basics/type-of-function.html

huang-guanhua commented 4 years ago

好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

atsixian commented 4 years ago

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

应该是加void,因为什么都没返回

Azir1 commented 4 years ago

@Deerhound579

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

应该是加void,因为什么都没返回

正解

HLOVEYOU8596 commented 4 years ago

也许生活就该这样

HLOVEYOU8596 commented 4 years ago

嘻嘻嘻

jinghh commented 4 years ago
interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}

既然接口定义已经说明了函数参数的类型,那么 mySearch 在赋值的时候 function(source:string,subSting:string)又定义了一次 是不是有点多余?我试了下直接写 成 mySearch = function(source,subString)就可以了

wangluyao959 commented 4 years ago

@jinghh

interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}

既然接口定义已经说明了函数参数的类型,那么 mySearch 在赋值的时候 function(source:string,subSting:string)又定义了一次 是不是有点多余?我试了下直接写 成 mySearch = function(source,subString)就可以了

我认为不能这么去写,在我的理解,ts是对js的写法不规范进行的规范化处理,如果你这么写的话岂不是没任何意义;还有就是 mySearch = function(source,subString)这个写法可以直接在ts中编译,和之前定义的接口没有任何关系,接口是抽象的,需要有一个变量去实现它,单纯的定义一个接口没有任何意义,。

andyComeOn commented 4 years ago

@Deerhound579

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

应该是加void,因为什么都没返回

您说的加 void 是加在哪?能贴一下代码吗。

Eryx-1994 commented 4 years ago

请问,如果当rest剩余参数和非必传参数共存的时候,那个优先权更加高,如何让这2个共存,我尝试过,把非必传放在rest前面,这时候非必传就变成了必传,但是放在后面rest会报错

strugglinglee commented 4 years ago

@mrnicai 请问,如果当rest剩余参数和非必传参数共存的时候,那个优先权更加高,如何让这2个共存,我尝试过,把非必传放在rest前面,这时候非必传就变成了必传,但是放在后面rest会报错

这种情况可以给非必传加个默认值undefined吧

DongLee0504 commented 4 years ago

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

function reverse(x: number): number function reverse(x: string): string function reverse(x: string | number): string | number { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else { // 注意这里 return x.split('').reverse().join(''); } } 这样写就不会报错 if else if 总有else条件没判断

chenle19 commented 4 years ago

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

我也觉得奇怪我觉得可以直接简化成这样: interface SearchFunc { (source: string, subString: string): boolean; }

let mySearch: SearchFunc; mySearch = function(source, subString) { return source.search(subString) !== -1; } 毕竟根据 类型推论 source和subString都会被接口推算出什么类型的 我不明白代码那么啰嗦的意义在哪里

wangluyao959 commented 4 years ago

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

我也觉得奇怪我觉得可以直接简化成这样: interface SearchFunc { (source: string, subString: string): boolean; }

let mySearch: SearchFunc; mySearch = function(source, subString) { return source.search(subString) !== -1; } 毕竟根据 类型推论 source和subString都会被接口推算出什么类型的 我不明白代码那么啰嗦的意义在哪里

虽然我也没有太仔细去研究,我是这么觉得的,接口是一个抽象的,上述代码mySearch是SearchFunc接口的实现类,表明 这个方法需要按照SearchFunc约束的格式去定义,之后是将另一个函数赋值类mySearch ,我们不知道要赋值的函数的参数类型 以及返回值类型是什么,所以仍然需要去进行一次定义。

chenle19 commented 4 years ago

@wangluyao959

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

我也觉得奇怪我觉得可以直接简化成这样: interface SearchFunc { (source: string, subString: string): boolean; }

let mySearch: SearchFunc; mySearch = function(source, subString) { return source.search(subString) !== -1; } 毕竟根据 类型推论 source和subString都会被接口推算出什么类型的 我不明白代码那么啰嗦的意义在哪里

虽然我也没有太仔细去研究,我是这么觉得的,接口是一个抽象的,上述代码mySearch是SearchFunc接口的实现类,表明 这个方法需要按照SearchFunc约束的格式去定义,之后是将另一个函数赋值类mySearch ,我们不知道要赋值的函数的参数类型 以及返回值类型是什么,所以仍然需要去进行一次定义。

可是我们按照SearchFunc约定的格式去定义,将另一个函数赋值类mySearch,那么这个表达式函数就应该是按照SearchFunc的约定,不然就会报错,既然必须一样的情况下,那么我又何必重新赋值一遍呢,如果是将另外一个具名函数赋值给mySearch,我觉得那样的情况下,具名函数给参数定义类型和定义return类型比较有意义,那样是为了验证

Wonder233 commented 4 years ago
interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}

这里是不是省略了列出匿名函数返回值类型。 如果省略这点,那么编译器就是通过推断得出的类型而不是手动添加的吧?

whastever commented 4 years ago

@Azir1

@Deerhound579

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

应该是加void,因为什么都没返回

正解

应该不用加 void; 入参就定义了,只接收 string | number 的变量,如果入参错误了,就不会有返回空值了。

weiweidong1993 commented 4 years ago

@andyComeOn

@Deerhound579

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

应该是加void,因为什么都没返回

您说的加 void 是加在哪?能贴一下代码吗。

直接把else if 改成 else,括号中的条件去掉即可. typescript 检查到可能既不是number也不是string类型的入参 此时 函数就没有返回值了

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string  {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else  {
        return x.split('').reverse().join('');
    }
}

console.log(reverse('aaaccddd'))
console.log(reverse(1526234))
console.log(reverse('日照老年人人老照日'))
console.log(reverse('大波美人鱼人美波大'))

console.log(typeof reverse(123))
console.log(typeof reverse('123'))

当然也可以改为void 或者 undefined

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}
weiweidong1993 commented 4 years ago

@HLOVEYOU8596

嘻嘻嘻

@mrnicai 请问,如果当rest剩余参数和非必传参数共存的时候,那个优先权更加高,如何让这2个共存,我尝试过,把非必传放在rest前面,这时候非必传就变成了必传,但是放在后面rest会报错

直接给个默认值不就得了 xxx='default'

justcho commented 3 years ago

加油加油

xjphhh commented 3 years ago

let mySum: (x: number, y: number) => number = function (x: number, y: number): number { return x + y; }; 不就可以简写为 let mySum: (x: number, y: number) => number = function (x, y) { return x + y; };

GuanLola commented 3 years ago

重载老是eslint报错already defined

JackyM06 commented 3 years ago

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

不会报错,由于函数形参被设置为了string or number,因此一旦能进入函数,那么就一定会返回正确的值

lzzqwe commented 3 years ago

@HLOVEYOU8596

嘻嘻嘻

我IC阿搜谱擦拭擦市场

ThingsChange commented 3 years ago

@mrnicai 请问,如果当rest剩余参数和非必传参数共存的时候,那个优先权更加高,如何让这2个共存,我尝试过,把非必传放在rest前面,这时候非必传就变成了必传,但是放在后面rest会报错

非必传 你不觉得和rest参数重复了吗

yclgkd commented 3 years ago

@andyComeOn

@Deerhound579

@huang-guanhua 好像最后reverse函数的例子,应该还要加上undefined,不然会ts报错吧

应该是加void,因为什么都没返回

您说的加 void 是加在哪?能贴一下代码吗。

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}
ggg1it commented 3 years ago

function buildName(firstName: string, lastName: string = 'Cat') { return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom');

有一点是打印 tom 的话 返回的值 只有 Tom、 为什么不带有默认值呢、、

yclgkd commented 3 years ago

function buildName(firstName: string, lastName: string = 'Cat') { return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom');

有一点是打印 tom 的话 返回的值 只有 Tom、 为什么不带有默认值呢、、

image

不太明白你的意思

ggg1it commented 3 years ago

@yclgkd

function buildName(firstName: string, lastName: string = 'Cat') { return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom');

有一点是打印 tom 的话 返回的值 只有 Tom、 为什么不带有默认值呢、、

image

不太明白你的意思

应该是我表述的不够清楚
function buildNameB(firstName: string = 'Tom', lastName: string) { return firstName + ' ' + lastName; } let tomcatb = buildNameB('Tom', 'Cat'); let catb = buildName('Cat');

console.log(catb); // 只有 Cat 没有默认值 Tom

ClishWang commented 3 years ago

@onePieceGuo 请问,如果当rest剩余参数和非必传参数共存的时候,那个优先权更加高,如何让这2个共存,我尝试过,把非必传放在rest前面,这时候非必传就变成了必传,但是放在后面rest会报错

function reverse(x: number, y?: number, ...rest: Array<number>): number {
    console.log(rest);
    if (typeof y === 'number') {
        return x + y;
    }
    return x;
}

这样满足你的需求么?