首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在编译时捕获子类型分配给超级类型?

如何在编译时捕获子类型分配给超级类型?
EN

Stack Overflow用户
提问于 2019-05-29 00:20:57
回答 2查看 108关注 0票数 1

学识的那个

类型记录结构类型系统的规则是,如果xy至少具有与x相同的成员,则yx兼容

这允许将子类型的变量赋值给超级类型的变量。是否有一种方法可以获得编译时错误的分配?

(TypeScript游乐场

代码语言:javascript
复制
interface SuperT {
    field: string
}

// an explicitly declared subtype object for a supertype variable generates an error
const super1: SuperT = {field: 'value', extra: 1} // compile-time error: Type '{ field: string; extra: number; }' is not assignable to type 'SuperT'

function subTValue() { return {field: 'value', extra: 1} }
const super2: SuperT = subTValue() // no compile-time error, BUT HOW TO get a compile-time error here? 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-29 01:38:24

您需要不直接支持的精确类型。你可以做使用泛型和条件类型的各种技巧来接近它。这里有一种间接的方法:

代码语言:javascript
复制
interface SuperT {
    field: string
}

type Exactly<T, U extends T> = T & Record<Exclude<keyof U, keyof T>, never>;
const asExactlySuperT = <U extends Exactly<SuperT, U>>(superT: U) => superT;

const superOkay: SuperT = asExactlySuperT({ field: "a" }); // okay

function subTValue() { return { field: 'value', extra: 1 } }
const superBad: SuperT = asExactlySuperT(subTValue()); // error! 
// types of property "extra" are incompatible

链接到代码

这里的想法是,Exactly<T, U>将采用一个类型T和一个候选类型U,希望它与T完全匹配,不需要额外的属性。如果是这样,那么Exactly<T, U>将等于U。如果没有,Exactly<T, U>将将任何额外属性的属性类型设置为never。因为asExactlySuperT<U>()要求U extends Exactly<SuperT, U>,所以只有在U中没有额外的属性时才能发生。

希望这能有所帮助。祝好运!

票数 2
EN

Stack Overflow用户

发布于 2019-05-29 01:58:35

正如雷·图尔所发现的,一个非常类似问题的答案可以找到这里。(我一开始就知道这一点,我只是想检查一下杰卡尔兹的反应时间,令人印象深刻,@jcalz!)

基于这种方法,我的代码如下所示:

() { return a } function subTValue() { return { field: 'value', extra: 1 } } const super3: SuperT = doIdentity(subTValue()) // we do get a compile-time error! )">TypeScript游乐场

代码语言:javascript
复制
type StrictPropertyCheck<T, TExpected, TError> = Exclude<keyof T, keyof TExpected> extends never ? {} : TError

interface SuperT {
    field: string
}

function doIdentity<T extends SuperT>(a: T & StrictPropertyCheck<T, SuperT, "Only allowed properties of SuperT">) {
    return a
}


function subTValue() { return { field: 'value', extra: 1 } }

const super3: SuperT = doIdentity(subTValue()) // we do get a compile-time error!
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56351586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档