Typescript 类型脚本类型签入开关语句、功能请求还是我做错了?

Typescript 类型脚本类型签入开关语句、功能请求还是我做错了?,typescript,Typescript,当传递“SpecificStringObj”类型的参数时,为什么typescript不知道f1返回字符串 接口F{ (s:AnyStringObj | SpecificStringObj):字符串|编号; } 接口AnyStringObj{ 文本:字符串; } 接口规范{ 案文:“具体性”; } 常数f1:F=s=>{ 开关(s.text){ 案例“特异性”: 返回“s”; 违约: 返回1; } }; 常量stringObj:SpecificStringObj={ 案文:“具体性” }; con

当传递“SpecificStringObj”类型的参数时,为什么typescript不知道
f1
返回字符串

接口F{
(s:AnyStringObj | SpecificStringObj):字符串|编号;
}
接口AnyStringObj{
文本:字符串;
}
接口规范{
案文:“具体性”;
}
常数f1:F=s=>{
开关(s.text){
案例“特异性”:
返回“s”;
违约:
返回1;
}
};
常量stringObj:SpecificStringObj={
案文:“具体性”
};
const newStringObj:AnyStringObj={text:f1(stringObj)};
此Typescript代码在对象的最后一行失败。文本中,错误消息为:

[ts]
Type 'string | number' is not assignable to type 'string'.
  Type 'number' is not assignable to type 'string'. [2322]
t.tsx(6, 3): The expected type comes from property 'text' which is declared here on type 'AnyStringObj'
(property) AnyStringObj.text: string
我可以用以下方法解决这个问题:

const newStringObj:AnyStringObj={text:f1(stringObj)as string};
我的问题是:既然我传递了一个“SpecificStringObj”,为什么typescript不知道函数将返回字符串



附加问题:这是否适用于功能请求?

Typescript不会进行这种分析。当它试图找出
f1
返回的内容时,它只会查看函数的签名。在签名中,
anyStringObj
string
之间没有明确的关系(它们在参数和返回联合中处于同一位置的事实并不构成关系)

要帮助编译器完成此任务,可以使用重载或条件类型:

重载版本:

interface f {
    (s: specificStringObj): string;
    (s: anyStringObj): number;
    (s: anyStringObj | specificStringObj): string | number;
}

interface anyStringObj {
    text: string;
}

interface specificStringObj {
    text: "specificity";
}

const f1: f = ((s:anyStringObj | specificStringObj): string | number => {
    switch (s.text) {
        case "specificity":
            return "s";
        default:
            return 1;
    }
}) as f;

const stringObj: specificStringObj = {
    text: "specificity"
};

const newStringObj: anyStringObj = { text: f1(stringObj) };
条件类型版本

interface f {
    <T extends anyStringObj | specificStringObj>(s: T):  T extends specificStringObj ? string : number;
}

interface anyStringObj {
    text: string;
}

interface specificStringObj {
    text: "specificity";
}

const f1: f = ((s:anyStringObj | specificStringObj): string | number => {
    switch (s.text) {
        case "specificity":
            return "s";
        default:
            return 1;
    }
}) as f;

const stringObj: specificStringObj = {
    text: "specificity"
};

const newStringObj: anyStringObj = { text: f1(stringObj) };
接口f{
(s:T:T):字符串OBJ?字符串:编号;
}
接口anyStringObj{
文本:字符串;
}
接口规范{
案文:“具体性”;
}
常量f1:f=((s:anyStringObj | specificStringObj):string | number=>{
开关(s.text){
案例“特异性”:
返回“s”;
违约:
返回1;
}
})作为f;
常量stringObj:specificStringObj={
案文:“具体性”
};
const newStringObj:anyStringObj={text:f1(stringObj)};
您正在寻找的


您所做的是重载返回方法。我正在做一些事情。。。如果你的界面名称是CamelCased,这将对我和其他人有所帮助。好的,切换到CamelCased顺便说一句,简明的问题表格应该是你问题的标题。帮助其他有同样问题的人找到它。不需要强制转换,当我尝试使用接口时,它们一直保留在那里,但后来切换到常规函数重载。哦,好的,我明白了,谢谢,但是Titians的回答更详细
interface AnyStringObj {
  text: string;
}

interface SpecificStringObj {
  text: "specificity";
}

function f1(s: SpecificStringObj): string;  
function f1(s: AnyStringObj): number;
function f1(s: AnyStringObj | SpecificStringObj): string | number { 
  switch (s.text) {
    case "specificity":
          return "s";
    default:
      return 1;
  }
}


const stringObj: SpecificStringObj = {
  text: "specificity"
};

const newStringObj: AnyStringObj = { text: f1(stringObj) };