函数最初不允许更改只读属性(例如name在 ES6 中):
let foo = function (n: number) {
return n;
}
foo.name = 'not foo'; // Cannot assign to 'name' because it is a read-only property
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,Writable使用了参考中的实用程序类型:
type Writable<T> = {
-readonly [K in keyof T]: T[K];
};
Run Code Online (Sandbox Code Playgroud)
1.只读name不受交集影响:
let writableFoo: typeof foo & { name: string } = foo;
writableFoo.name = 'not foo'; // Cannot assign to 'name' because it is a read-only property
Run Code Online (Sandbox Code Playgroud)
2.Writable不是name从函数类型获取的,也不是可调用的:
let writableFoo: Writable<typeof foo> = foo;
writableFoo.name = 'not foo'; // Property 'name' does not exist on type 'Writable<(n: number) => number>'
writableFoo(1); // This expression is not callable
Run Code Online (Sandbox Code Playgroud)
3.Writable获得name来自Function但仍不赎回:
let writableFoo: Writable<Function> = foo;
writableFoo.name = 'not foo';
writableFoo(1); // This expression is not callable
Run Code Online (Sandbox Code Playgroud)
4.Omit使用索引签名并且不可调用:
let writableFoo: Omit<typeof foo, 'name'> & { name: string } = foo;
writableFoo.name = 'not foo';
writableFoo(1); // This expression is not callable
Run Code Online (Sandbox Code Playgroud)
这里的目标是键入writableFoo以保持writableFoo可调用并允许name更改,最好不要修改其他属性Writable。它不会尝试解决特定的编码问题,而是调查特定类型的问题。
为什么 1 不会readonly通过交集类型影响修饰符?
name尽管2 被识别为typeof foo,但为什么没有得到foo.name?
2-4 如何在从 中删除readonly修饰符时获得调用签名name?
这样你就可以调用和写入name
interface Foo extends Function{
name: string
}
const d: Foo = function(){}
d.name ='not foo'
d()
Run Code Online (Sandbox Code Playgroud)
谢谢。它从技术上解决了问题,但 Function 忽略了函数的签名 d('should Cause TS error', 'for Unexpected args') (问题中没有提到,但似乎是一个合理的要求)。const 本身也能够消除错误,因为它的处理方式与 let 不同
type Incrementer = (x: number)=>string
interface Foo extends Incrementer{
name: string
}
let d: Foo = (x)=>'a'+x
d.name ='not foo'
d(1)
d('s') // string not expceted must be number
Run Code Online (Sandbox Code Playgroud)
如果您想要一般性答案,这里是您的Writable
interface Writable<T extends (...args: any) => any> {
(...arg: Parameters<T>): ReturnType<T>;
name: string
}
type Incrementer = (x: number, y: boolean) => string
let d: Writable<Incrementer> = (x, y) => 'a' + x + y
d.name = 'not foo' // no error
d(1, true) // no error
d('d', true) // 'd' is not assignable to number
d(2, 1) // 1 is not assignable to boolean
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
232 次 |
| 最近记录: |