反面例子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来实现。
@xyzingh image.png 你的意图是定义类型,实际上你最后的代码定义的是返回值 你把类型定义在这里了 image.png 你认为和这个有什么区别 let abc = (a: any, b: any): IAbc =>
楼主用的什么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 image.png "得到的应是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;
interface F { (): any; someValue: number } const f: F = Object.assign(() => {}, { someValue: 3 })
时隔一个月回来补上正确做法。 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, ";
}
官方描述混合类型:接口能够描述JavaScript里丰富的类型。 因为JavaScript其动态灵活的特点,有时你会希望一个对象可以同时具有上面提到的多种类型。
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 = ()=>{};