[英]in typescript, how to define a specialized version of a generic function?
[英]How to define a generic field copy function in TypeScript
我正在嘗試在 TypeScript 中定義通用字段副本 function 但未能使打字正常工作。 請參見下面代碼中的方法 4。 我的問題是,我如何編寫一個 function 可以使 TypeScript 打字正常工作並檢查目標類型和源類型?
長話短說:我正在從事一個從 NoSQL 數據庫讀取數據並通過 API 返回客戶端的項目。 從安全的角度來看,最好進行投影(顯式字段復制)以避免將來添加任何返回給客戶端的字段。 我正在尋找一種簡單的方法來做到這一點。
// ----------
// TypeScript type definition
// ----------
interface Student {
name: string
studentId?: string
}
interface StudentDbRecord extends Student {
createTimestamp: number
}
interface StudentApiResult extends Student {
// We use NoSQL, so ID is not part of the record
id: string
}
// ----------
// Database data
// ----------
const docId: string = '6542fdba-fcae-4b15-a1c8-72a2a57f51c7'
const dbRecord: StudentDbRecord = {
name: 'Chirs',
createTimestamp: Date.now()
}
// ----------
// Implementation
// ----------
// Method 1: An extra `createTimestamp` field is in `apiResult1` and returned to API caller
const apiResult1: StudentApiResult = {
...dbRecord,
id: docId
}
const apiResult2: StudentApiResult = {
id: docId,
name: dbRecord.name,
// Method 2: This result in a field with `undefined` value, which causes other issues
studentId: dbRecord.studentId
}
// Method 3: This works, but easier to make mistake because `studentId` is specified 3 times
const apiResult3: StudentApiResult = {
id: docId,
name: dbRecord.name
}
if (dbRecord.studentId !== null) { apiResult3.studentId = dbRecord.studentId }
// Method 4, this should be the best but unable to get it working in TypeScript
function copyField<D, S, K extends (keyof D & keyof S)>(dest: D, src: S, key: K): void {
if (src[key] !== undefined) {
// Error ts(2322): 'D' could be instantiated with an arbitrary type which could be unrelated to 'S'
dest[key] = src[key]
}
}
const apiResult4: StudentApiResult = {
id: docId,
name: dbRecord.name
}
copyField(apiResult4, dbRecord, 'studentId')
訣竅是只提交入站 dest 和 src 對象的最少類型。 看看我為你制作的最小復制品和這個游樂場的潛在解決方案
function copyField<Key extends keyof any, Value>(
key: Key,
source: { [K in Key]: Value },
dest: { [K in Key]: Value }
): void {
const sourceValue = source[key];
if (sourceValue !== undefined) {
dest[key] = sourceValue;
}
}
const rover: Dog = {
hasFleas: true,
hasStick: false,
};
const felix: Cat = {
hasFleas: false,
hasMouse: true,
};
const klaus: Fish = {
hasTeeth: false,
};
copyField("hasFleas", rover, felix);
//this is (correctly) a compiler error
copyField("hasFleas", felix, klaus);
interface Dog {
hasFleas: boolean;
hasStick: boolean;
}
interface Cat {
hasFleas: boolean;
hasMouse: boolean;
}
interface Fish {
hasTeeth: boolean;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.