javascript - Typescript string literal with duck-typed object - Stack Overflow

Typescript 1.8 introduced the string literal type. However, when passing in an object as a parameter as

Typescript 1.8 introduced the string literal type. However, when passing in an object as a parameter as in the following:

const test = {
    a: "hi",
    b: "hi",
    c: "hi"
};

interface ITest {
    a: "hi" | "bye"
}

function testFunc (t: ITest) {

}

testFunc(test);

It fails with:

Argument of type '{ a: string; b: string; c: string; }' is not assignable to parameter of type 'ITest'. Types of property 'a' are inpatible. Type 'string' is not assignable to type '"hi" | "bye"'. Type 'string' is not assignable to type '"bye"'.

I would expect this to work since it meets the requirements of the interface, but I might be overlooking something.

Typescript 1.8 introduced the string literal type. However, when passing in an object as a parameter as in the following:

const test = {
    a: "hi",
    b: "hi",
    c: "hi"
};

interface ITest {
    a: "hi" | "bye"
}

function testFunc (t: ITest) {

}

testFunc(test);

It fails with:

Argument of type '{ a: string; b: string; c: string; }' is not assignable to parameter of type 'ITest'. Types of property 'a' are inpatible. Type 'string' is not assignable to type '"hi" | "bye"'. Type 'string' is not assignable to type '"bye"'.

I would expect this to work since it meets the requirements of the interface, but I might be overlooking something.

Share Improve this question asked Apr 5, 2016 at 1:42 Alexander MattoniAlexander Mattoni 4558 silver badges21 bronze badges 2
  • a, b, and c are string type in test and the "hi" | "bye" type in your interface. – nullforce Commented Apr 5, 2016 at 1:46
  • That makes sense, even though it's a bit counter intuitive. Thanks. – Alexander Mattoni Commented Apr 5, 2016 at 1:51
Add a ment  | 

1 Answer 1

Reset to default 13

The type of test.a has been inferred as string and not "hi". The piler is paring the types and not the initial string expression.

In order to make this work you need to type that property as "hi" | "bye":

type HiBye = "hi" | "bye";

const test = {
    a: "hi" as HiBye,
    b: "hi",
    c: "hi"
};

interface ITest {
    a: HiBye
}

function testFunc (t: ITest) {
}

testFunc(test);

Note that in the original case it wouldn't make sense for the piler to infer the type of test.a to be "hi" because you can assign a different value to test.a before it reaches testFunc(test)—ex. test.a = "not hi".

Side note: It's good the piler doesn't infer the type the be the string expression for even constant string variables. That would also lead to a lot of annoyances... imagine this:

const myVariableTypedAsHi = "hi";   // implicitly typed as "hi"
let otherVar = myVariableTypedAsHi; // otherVar implicitly typed as "hi"

otherVar = "test"; // error: cannot assign `"test"` to `"hi"`—well that would be annoying

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744413446a4572997.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信