gpt4 book ai didi

typescript - 错误的功能分配

转载 作者:行者123 更新时间:2023-12-03 17:09:13 24 4
gpt4 key购买 nike

我在非严格模式下遇到问题,这是我的代码
我可以将类型错误的函数分配给类型化变量。
我犯错了吗?
谢谢。

interface A {
f1( ) : void;
}

interface B extends A {
f2( ) : void;
}

interface C {
f3( ) : void;
}

type expectA = ( a: A ) => void;
type expectB = ( b: B ) => void;


function testA( a: A ) {
console.log( "a" );
}

function testB( b: B ) {
console.log( "b" );
}

function testC( c: C ) {
console.log( "c" );
}


let v1: expectA = testA; // ok: assign type A to a type A
let v2: expectA = testB; // ok: assign type B (extending A) to a type A
let v3: expectA = testC; // fail -> normal: error TS2322: Type '(c: C) => void' is not assignable to type 'expectA'.
let v4: expectB = testA; // ok -> **abnormal**: there is no error in !strict mode

最佳答案

TypeScript 实际上是在保护您不要在这里做一些愚蠢的事情,但它以一种令人困惑的方式这样做。
让我们将您的示例简化为接口(interface) AB .

interface A {
f1( ) : void;
}

interface B extends A {
f2( ) : void;
}

type expectA = ( a: A ) => void;
type expectB = ( b: B ) => void;


function testA( a: A ) {
a.f1();
}

function testB( b: B ) {
b.f1();
b.f2();
}


const v1: expectA = testA;
const v2: expectA = testB; // error: Property 'f2' is missing in type 'A' but required in type 'B'
const v3: expectB = testB;
const v4: expectB = testA;
乍一看,底部的结果只有 v2有错误可能看起来违反直觉。如果 B扩展 A ,那你为什么不能用 B您可以在任何地方使用 A ?
答案是因为我们在这里处理函数。仔细看 testB()的实现.它调用属性 b.f2()因为它期望它的参数 b将拥有该属性。但是 const v2: expectB 的左侧等价于类型 (a: A) => void . A 类型的参数没有 f2() .所以我们告诉 TypeScript 关于 v2 的正确类型是什么冲突的事情。是;要么是具有 a: A 的函数在这种情况下 a.f2()调用不安全,或者它是具有 b: B 的函数在这种情况下它是安全的。这是一个悖论!
(请记住,这与 testB 是否实际尝试调用 b.f2() 无关;关键是它可能会根据其参数类型的设置方式,导致 v2 中出现运行时错误。设想。)
现在为 const v4你说你认为这没关系是“不正常的”,但是如果我们再次仔细查看函数,我们会发现它是有道理的。如果你传递了一个类型 AB可变为 testA() ,没有可能的错误,因为它永远不会尝试访问 f2()属性(property)。
另请注意 extends在 TypeScript 中并不像您期望的那样工作。写作 interface B extends A只是说 B将继承 A 的所有属性.它不建立任何允许 B 的关系。代表 A 的任何实例.这种行为称为“多态性”,要做到这一点,您需要使用类来代替,例如 class B extends A implements A .
class A {
foo = '';
}

class B extends A implements A {
bar = '';
}

let isA = new A();
isA = new B(); // this is fine because B implements A
let isB = new B();
isB = new A(); // error: Property 'bar' is missing in type 'A' but required in type 'B'

关于typescript - 错误的功能分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66916829/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com