反面例子1:
function abc(a: string, b: number): void;
function abc(a: string): void;
function abc(a: any, b:any): void {
if (typeof b === 'number'){}
else {}
}
abc.someAttr = ()=>{};
反面例子2:
interface IAbc {
(a: string, b: number): void;
(a: string): void;
someAttr: ()=>void;
}
let abc: IAbc = (a: any, b:any) => {
if (typeof b === 'number'){}
else {}
}
abc.someAttr = ()=>{};
现在这样凑合着:
interface IAbc {
(a: string, b: number): void;
(a: string): void;
someAttr?: ()=>void; // 加了个问号
}
let abc: IAbc = (a: any, b?:any) => {
if (typeof b === 'number'){}
else {}
}
abc.someAttr = ()=>{};
请问有人知道正确手法吗?
为啥不弄个类然后内部函数弄成静态?
1、你把IAbc定义为返回值了 2、a,b定义为any也不合适 正确写法:
interface IAbc {
a: string;
b?: number;
}
function abc(iabc: IAbc): void {
if(typeof iabc.b == 'number') {
} else {
}
}
但是有个问题是你说的静态属性,TS应该是没有这个东西的 你可以使用类,类有静态属性,但似乎不是你想要的
interface IAbc { (a: string, b: number): void; (a: string): void; } 这是函数重载。后面要写any来实现。
IAbc不是abc的返回值类型,就是它的类型啊?
@xyzingh 我知道,返回值相同没必要重载,重载是针对返回不同的类型,可选属性就可以了
@xyzingh 你的意图是定义类型,实际上你最后的代码定义的是返回值 你把类型定义在这里了 你认为和这个有什么区别 let abc = (a: any, b: any): IAbc =>
ts视频教程看看,希望对你有帮助: https://pan.baidu.com/s/17jllW0igIOWjM3YCvWS-bg
楼主用的什么ide? 你这代码全部都会报类型错误啊 首先ts没有重载,你想想ts是要编译成js的,函数也就是原型链上的对象,是不可能一条链绑两个同名属性的. 如果要做你类似的东西,应该用默认参数 其次你那个明明是定义了一个对象的声明,但给了一个函数. 而且函数带静态属性本身就是很诡异的事情. 老老实实类加静态变量加静态方法不好么?
class A {
static someAttr = "";
fun1(a: string, b: number = 0) {
}
}
@JsonSong89
有重载啊,看看文档去
“首先ts没有重载,你想想ts是要编译成js的,函数也就是原型链上的对象,是不可能一条链绑两个同名属性的.”
1、首先TS只是在做类型检查,并没有绑定,只是更容易让你发现错误,重载是解决针对输入不同,返回不同类型值的类型检查的
2、”函数也就是原型链上的对象“,最好还是区分开,a function () {} , let ressult = a(); const b = { a : 1}, let res = b.a;
@JsonSong89 给的反面例子,自然会报类型错误。第三个凑合的例子是通过的。 TS有重载: https://www.typescriptlang.org/docs/handbook/functions.html#overloads 并且可以声明接口给函数用 https://www.typescriptlang.org/docs/handbook/interfaces.html#function-types 接口里声明多个函数类型是重载的本质。 请自己补课 @fuxingZhang "你认为和这个有什么区别 let abc = (a: any, b: any): IAbc => {…}" 这样执行 abc(…, …); 得到的应是IAbc类型,也就是一个函数且有属性someAttr IAbc我是用在abc上的,不是abc执行得到的返回值啊。
重载只是随手举个例子,帖子问的是定义函数添加静态属性。
@xyzingh ”得到的应是IAbc类型,也就是一个函数且有属性someAttr“ 是对象,不是函数 你的写法就是在定义返回值,和我写的那个是一样的,而你的意图是定义参数,所以你写的和你想要的不一样
@fuxingZhang 嗯,这里是我没说清楚,ts只是类型声明时的重载,编译后就没了. 后面那个是语病,我是想说(你这两个)函数不可能同时存在于一条链上(不同链会覆盖).
这样?
interface IAbc {
(a: string, b?: number): void
[propName: string]: () => void | undefined
}
const abc = ((a: string, b?: number) => {
if (typeof b === 'number') {
console.log(b)
} else {
console.log(a)
}
}) as IAbc
abc.someAttr = () => {
console.log('some attr')
}
abc('hello')
abc('hello', 123)
abc.someAttr()
哈,我刚想到改过来,你就发了。
不写在 class 里 可读性太差了,
function abc(){
};
function staticMethod(){
}
abc.staticMethod = staticMethod;
微软不推荐ts (IAbc) 这个写法。
interface F { (): any; someValue: number } const f: F = Object.assign(() => {}, { someValue: 3 })
没搞懂,静态方法貌似只有类里面的方法有,普通方法没有静态方法这个概念吧。void的意义应该是无有效返回值,不是静态方法,这个概念都不一样。
时隔一个月回来补上正确做法。 https://www.tslang.cn/docs/handbook/declaration-merging.html
function buildLabel(name: string): string {
return buildLabel.prefix + name + buildLabel.suffix;
}
namespace buildLabel {
export let suffix = "";
export let prefix = "Hello, ";
}
@xyzingh 现在尽量少用namespace了吧。那是ecma模块系统前的一个解决方案